因此,在以下情况下,我一直怀疑重定向的工作原理:
我输入“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
生成的。
为什么后一种情况下的输出与前一种情况不同?我实际上可以看到“>”符号所以它改变了它的行为?
答案 0 :(得分:11)
ls
测试其输出流以查看它是否是终端,并根据它修改其行为。
记录在案; man
的{{1}}页面记录了几个取决于输出是否为终端的内容:
ls
(对于多列输出)是默认值,否则-C
(单列)是默认值。-1
或-l
且输出是终端,则所有文件大小或块的总和将分别打印在列表之前的一行上。-s
是默认值。这会将非图形字符打印为“?”。否则,-q
和-v
是默认值。我对-w
和-v
之间的区别有点不清楚。我所说的文件-w
强制“未经编辑的非图形字符打印”和-v
强制“打印不可打印的字符。”答案 1 :(得分:3)
它无法看到符号(由shell解释),但它可以找出输出是否转到终端。
为了将文件很好地组织到列中,ls
需要知道终端的宽度。当输出设备不是终端时,它只是不知道如何格式化其输出。
此行为的另一个好处是,您可以执行ls | wc -l
之类的操作,而无需担心同一行上的多个文件。 (不过,您仍然需要担心包含换行符的文件名。)
答案 2 :(得分:2)
ls
使用一个名为ls_mode
的内部变量,它对于Gnu coreutils实现的3 ls“type”命令是不同的。对于ls,它是LS_LS
。对于dir,它是LS_MULTI_COL
,对于vdir,它是LS_LONG_FORMAT
。实际的ls program表示根据此变量,输出格式将发生变化。对于ls
,这就是它所说的
如果ls_mode是LS_LS,输出格式取决于是否 输出设备是终端。这是'ls'计划。
这与您使用输出位置更改格式的体验一致。如果您对dir
尝试相同的操作,则不会。