Mât*_*man 12 command-line ls io-redirection tty
命令如何ls知道它的标准输出是什么?
ls根据目标标准输出的不同,操作似乎有所不同。例如,如果我这样做:
ls /home/matt/tmp
Run Code Online (Sandbox Code Playgroud)
结果是:
a.txt b.txt c.txt
Run Code Online (Sandbox Code Playgroud)
但是,如果我这样做
ls /home/matt/tmp | cat
Run Code Online (Sandbox Code Playgroud)
结果是(即每个结果换行):
a.txt
b.txt
c.txt
Run Code Online (Sandbox Code Playgroud)
该进程为标准输出传递了一个文件描述符 1 对吗?它如何确定如何格式化结果?文件描述符是否显示信息?
Sté*_*nez 22
该ls程序用于isatty()了解 fd 1 是 tty 还是其他内容(管道、文件等)。来自man 3 isatty:
Run Code Online (Sandbox Code Playgroud)int isatty(int fd);描述
该isatty()函数测试是否fd是指向终端的打开文件描述符
更新:ls.c来自 coreutils 的第 1538 行(git 修订版 43a987e1):
if (isatty (STDOUT_FILENO))
{
format = many_per_line;
/* See description of qmark_funny_chars, above. */
qmark_funny_chars = true;
}
Run Code Online (Sandbox Code Playgroud)
(many_per_line应该是自我描述的。)
不是一个确切的答案,而是一个例子。在bash脚本也可以达到类似的效果test/[[的-t:
-t FD True if FD is opened on a terminal.
像这样使用它:
bash-4.2$ where() { [[ -t 1 ]] && echo 'my output goes to TTY' || echo 'my output is redirected'; }
bash-4.2$ where
my output goes to TTY
bash-4.2$ where | cat
my output is redirected
bash-4.2$ where > test.file
bash-4.2$ cat test.file
my output is redirected
Run Code Online (Sandbox Code Playgroud)