我想我可能忽略了关于 shell 的一个相对基本的点。输出从LS默认情况下,命令用换行符分隔输出,但 shell 将输出显示在一行上。
谁能向我解释一下吗?我一直认为输出只是用空格分隔,但现在我看到输出用换行符分隔,我希望输出显示在单独的行上。
例子:
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
答案1
当您通过管道输出时,ls
行为会有所不同。
这一事实隐藏在信息文档:
如果标准输出是终端,则输出按列排列(垂直排序),控制字符输出为问号;否则,每行列出一个输出,并按原样输出控制字符。
为了证明这一点,请尝试运行
ls
进而
ls | less
这意味着,如果您希望保证输出每行一个文件,无论它是通过管道传输还是重定向,您都必须运行
ls -1
(-1
是第一名)
或者,您可以ls | less
通过运行强制按列输出
ls -C
(-C
是大写C)
答案2
您的发现凸显了解析 的输出始终是一个坏主意的主要原因ls
。请参阅 Greg 的 wiki完整解释。
逆向思考你的问题。您注意到 ls 有时在其输出之间打印换行符,有时不打印换行符。对于在脚本中使用或被标志强制时-1
,它确实如此。每个文件末尾有一个换行符。有什么不保证每个换行符代表一个新文件名。事实上,如果文件名本身包含换行符,则 ls 的输出将绝对无法解析。考虑这些文件名:
file1
file2\nfile3
file4
当你的ls -1
目录中包含该目录时,你会得到如下所示的内容:
file1
file2
file3
file4
您不会自然地认为有四个文件吗?解析 ls 输出的任何脚本也是如此。实际上,存在三个文件,其中一个的名称很棘手,但您无法从 ls.* 的输出中找出这一点。
* 除非您使用该-l
标志并注意到输出被中断,否则您的脚本仍然会阻塞。