-3

我的文件夹中有 2 个文件,如下所示

$ ls -l
total 1
-rw-r--r-- 1 user user-group 0 May 10 14:49 test
-rw-r--r-- 1 user user-group 0 May 10 14:49 test1

列出文件显示正常。但是为什么下面的命令会在 bash 中将两行合并为一行?

$ echo `ls -l`
total 1 -rw-r--r-- 1 user user-group 0 May 10 14:49 test -rw-r--r-- 1 user user-group 0 May 10 14:49 test1
4

2 回答 2

6

为了补充Colwin 的有效答案为什么需要双引号

如果您传递未加引号的命令替换(例如,`ls -l`更好,$(ls -l)或变量引用(例如,$var),shell在将参数传递给命令之前修改命令输出/变量值
这适用于所有与 POSIX 兼容的 shell,而不仅仅是bash.

具体来说,执行以下所谓的外壳扩展

  • word-splitting:输出被空格分割成(可能)多个单词,包括换行符(默认情况下;分割字符可以通过设置)$IFS

  • globbing(文件名扩展):每个结果词都被解释为文件名模式,并与当前目录中的文件再次匹配,每个匹配的文件名成为自己的词,所有结果词都替换原来的词;默认情况下,如果没有匹配项,则单词保持原样。

然后将生成的单词作为单独的参数传递给目标命令。

相比之下,如果您双引号命令替换 ("$(ls -l)"或变量引用 ( "$var"),则不会发生这些扩展,并且输出/值将按原样传递给目标命令。


因此,在手头的情况下:

  • 外壳从输出中删除所有换行符ls -l
  • 然后将生成的单词作为多个参数单独传递给echo

echo只需将您传递给它的多个参数与空格连接起来,这就是为什么您会在问题中看到单行输出。

简而言之:由于没有双引号`ls -l`echo `ls -l`打印一个以空格分隔的单行列表,其中包含来自 的输出中的单词ls -l

于 2017-05-10T14:56:12.180 回答
4

由于您在此处使用命令替换和 echo,为了让 echo 在多行上显示您的输出,您需要引用输出。

$ echo "`ls -l`"
于 2017-05-10T13:17:52.963 回答