将多行命令输出传递给 echo 仅输出一行

Passing multi-line command output to echo outputs only a single line

我的文件夹中有 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

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

$ echo "`ls -l`"

补充为什么需要双引号:

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

具体来说就是下面所谓的shell expansions 被执行:

  • 分词:输出被分成(可能)多个个词whitespace,包括换行符(默认;拆分字符可以通过$IFS设置)

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

结果词然后被作为单独的参数传递给目标命令。

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


因此,在手头的案例中:

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

echo 只是将您传递给它的 多个 参数与 space 连接起来,这就是为什么您看到单行输出的原因你的问题。

简而言之:由于没有双引号 `ls -l`echo `ls -l` 打印一个 space 分隔的单行列表,其中包含的单词ls -l.

的输出