ls 输出中文件名之间的魔术分隔符是什么?

Chr*_*s B 20 ls pipe newlines

ls(不带参数)的输出似乎用换行符分隔文件名。

证据:

  • ls | grep foo按预期工作,grep将每个文件名视为单独的输入行。

  • ls > files.txt; vim files.txt --> 在 Vim 中,每个文件都在单独的一行

然而在终端中,输出ls将多个文件放在一行上,用空格分隔文件名以形成很好对齐的列:

$ ls
a.txt  b.txt  c.txt
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,ls 如何做到这一点?

是否使用一些特殊的控制字符来“伪造”换行符?或者它是否知道它的输出何时通过管道传输到另一个命令,并在这种情况下以不同的方式格式化输出?

Dan*_*son 24

或者它是否知道它的输出何时通过管道传输到另一个命令,并在这种情况下以不同的方式格式化输出?

是的。来自完整手册(info ls如果安装了文档,则可用):

如果标准输出是终端,则输出为列(垂直排序),控制字符输出为问号;否则,每行列出一个输出,并按原样输出控制字符。

如果你喜欢一列输出,你可以运行

ls -1
Run Code Online (Sandbox Code Playgroud)

也可以在终端中获取它。

  • 具体来说,函数`ls` 用于确定输出是否为终端是`isatty(3)`。 (7认同)

小智 10

ls当您通过管道输出时检测到它。您可以在文档中看到它:

如果标准输出是终端,则输出为列(垂直排序),控制字符输出为问号;否则,每行列出一个输出,并按原样输出控制字符。

如果您希望将输出中的每个文件放在单独的行上,而不管管道重定向如何,您可以使用

ls -1
Run Code Online (Sandbox Code Playgroud)