ls的输出有换行符,但显示在一行上。为什么?


41

我认为我可能忽略了关于Shell的一个相对基本的观点。缺省情况下,ls命令的输出用换行符分隔输出,但是外壳程序将输出显示在一行上。

有人可以向我解释吗?我一直以为输出只是用空格分隔,但是现在我看到输出用换行符分隔,我希望输出显示在单独的行上。

例:

cpoweradm@debian:~/lpi103-4$ ls text*
text1  text2  text3

od显示输出用换行符分隔:

cpoweradm@debian:~/lpi103-4$ ls text* | od -c
0000000   t   e   x   t   1  \n   t   e   x   t   2  \n   t   e   x   t
0000020   3  \n
0000022

如果存在换行符,那么为什么输出不显示为:

text1 
text2
text3

Answers:


44

用管道传输输出时,ls行为会有所不同。

这个事实隐藏在信息文档中

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

为了证明这一点,请尝试运行

ls

接着

ls | less

这意味着,如果要确保输出每行只有一个文件,无论是通过管道传输还是重定向,都必须运行

ls -1

-1是第一名)

或者,您可以ls | less通过运行来强制输出列

ls -C

-C是大写的C)


6
@theconnorpower:它非常特定于ls。它很有用,但显然前后矛盾且令人惊讶。但是请注意,某些产生彩色输出的命令也会在通过管道传输时去除颜色。
Mikel

5
@theconnorpower:Trivia:Unix的发明者继续编写Plan9。在Plan9中,ls总是每行打印一个,并且lc总是以列打印。
Mikel

2
@theconnorpower:也有程序读取终端的大小,并相应地调整其输出,例如在Debian dpkg -l上将使用屏幕的整个宽度,但是如果要打印到管道,则假定终端为80列宽,并在必要时缩写输出以使其适合。
Mikel

1
@Mikel有趣的是听到Plan9中的ls / lc差异。感谢您的详细回答。
zod90

1
程序如何确定其输出是否重定向到文件或它是否要进入外壳?
user2820379

4

您的发现凸显了解析输出ls总是一个坏主意的主要原因。有关完整说明,请参见Greg的Wiki 。

反过来思考你的问题。您注意到ls有时会在某些输出之间打印出换行符,有时不会在它们之间打印换行符。对于在脚本中使用或在-1标志强制下使用,确实可以。每个文件末尾有一个换行符。什么也不能保证每一个新行代表一个新的文件名。实际上,如果文件名本身包含换行符,则ls的输出将绝对无法解析。考虑以下文件名:

file1
file2\nfile3
file4

当其中ls -1包含一个目录时,您将获得如下所示的内容:

file1
file2
file3
file4

您自然不会假设有四个文件吗?解析ls输出的任何脚本也将如此。实际上,这里有三个文件,其中一个文件名很棘手,但是您不能从ls的输出中弄清楚。*

*除非您使用该-l标志并且注意到输出已中断,但是您的脚本仍然会阻塞。


3
如果您确实需要解析的输出ls,则该-b选项可以提供帮助。原来换行成\n
米克尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.