所以,我一直怀疑重定向在以下情况下的工作原理:
我输入“ls”,所有文件名都用空格分隔:
test$ touch a b c test$ ls a b c
我使用“>”将 STDOUT 重定向到文件:
test$ ls > ls.txt test$ cat ls.txt a b c ls.txt
有趣的是,格式发生了变化,文件名由换行符分隔。似乎输出是由ls -1
.
为什么后一种情况下的输出与前一种情况不同?ls 真的可以看到“>”符号,从而改变它的行为吗?
ls
测试其输出流以查看它是否是终端,并根据它修改其行为。
这是记录在案的;该man
页面ls
记录了取决于输出是否为终端的几件事:
-C
(对于多列输出)是默认值,否则-1
(单列)是默认值。-l
or-s
并且输出是终端,则所有文件大小或块的总和分别打印在列表之前的一行上。-q
则为默认值。这会将非图形字符打印为“?”。否则,-v
和-w
是默认值。我有点不清楚-v
和之间的区别-w
。我的文档说-v
强制“未经编辑打印非图形字符”和-w
强制“原始打印不可打印字符”。</li>
它看不到符号(由 shell 解释),但它可以查明输出是否到终端。
为了将文件很好地组织到列中,ls
需要知道终端的宽度。当输出设备不是终端时,它只是不知道如何格式化其输出。
这种行为的另一个很好的结果是你可以做一些事情,ls | wc -l
而不用担心同一行上有多个文件。(不过,您仍然需要担心包含换行符的文件名。)