Linux 为什么重定向符号会改变ls的行为?
因此,我一直怀疑重定向在以下情况下如何工作:Linux 为什么重定向符号会改变ls的行为?,linux,bash,unix,Linux,Bash,Unix,因此,我一直怀疑重定向在以下情况下如何工作: 我键入“ls”,所有文件名都用空格分隔: test$ touch a b c test$ ls a b c 我使用“>”将标准输出重定向到文件: test$ ls > ls.txt test$ cat ls.txt a b c ls.txt 有趣的是,格式发生了变化,文件名由换行符分隔。输出似乎是由ls-1生成的 为什么后一种情况下的输出与前一种情况下的输出不同?ls真的能看到“>”符号从而改变它的行为吗?ls测试它的输出流以确定它是
test$ touch a b c
test$ ls
a b c
test$ ls > ls.txt
test$ cat ls.txt
a
b
c
ls.txt
ls-1
生成的
为什么后一种情况下的输出与前一种情况下的输出不同?ls真的能看到“>”符号从而改变它的行为吗?
ls
测试它的输出流以确定它是否是一个终端,并根据这一点修改它的行为
这是有案可查的;ls
的man
页面记录了取决于输出是否为终端的几件事情:
- 如果输出是终端,
(用于多列输出)是默认值,否则-C
(一列)是默认值-1
- 如果使用了
或-l
,且输出为终端,则在列表前的一行上分别打印所有文件大小或块的总和-s
- 如果输出是终端,
是默认值。这会将非图形字符打印为“?”。否则,-q
和-v
是默认值。我不太清楚-w
和-v
之间的区别。我的文档中说,-w
强制“非图形字符的未编辑打印”,而-v
强制“非可打印字符的原始打印”-w
ls
需要知道终端的宽度。当输出设备不是终端时,它就不知道如何格式化输出
这种行为的另一个好结果是,您可以执行类似于
ls | wc-l
的操作,而不必担心同一行上有多个文件。(不过,您仍然需要担心包含换行符的文件名。)ls
使用名为ls_mode
的内部变量,这与Gnu coreutils实现的3个ls“type”命令不同。例如,它是LS\u LS
。对于,它是LS\u MULTI\u COL
,对于,它是LS\u LONG\u格式
。实际值表示根据此变量,输出格式将发生变化。对于ls
,它是这样说的
如果ls_模式为ls_ls,则输出格式取决于
输出设备是一个终端。这是为“ls”计划准备的
这与您的格式随输出位置变化的经验是一致的。如果您对
dir
尝试相同的方法,则不会成功 好问题。数百万人多年来一直在使用ls
,他们也在想同样的事情。如果你想在重定向输出中添加列,请尝试ls-C
。基本上,是的ls
使用了与[-T1]
等效的代码,但由于ls
是用C编写的,而不是用sh编写的,因此它使用了具有相同语义的不同构造。@YuFu它调用POSIX函数isatty
(来自unistd.h
),这大概也是test
在给定标志-t
时调用的。对于GNU ls为True,对于具有相同行为的其他ls程序不一定为True。我不确定是否有任何其他ls
实现具有这种行为。基于这个问题,我假设正在讨论的是GNU ls。IIRC,“Interactive 386/ix”上的ls也做了同样的事情,那是在Linux之前,但不是在GNU之前,而且很可能没有GNU ls(因为它是一个许可的SysV unix,等等)。谢谢。我不会往回走那么远。:)