0

Echoing without quotes... 1 line. Fine.

$ echo $(ls -1dmb /bin/*) > test
$ wc -l test
1 test

Echoing with quotes... 396 lines. Bad.

$ echo "$(ls -1dmb /bin/*)" > test
$ wc -l test
396 test

The problem comes when using echo for writing a file and expanding a long variable.

Why does this happen? How to fix it?

4

2 回答 2

2

ls正在检测您stdout不是终端。

检查ls -1dmb /bin/* | catvs的输出ls -1dmb /bin/*。它是ls谁在拆分输出。

类似地,对于ls --color=autocase,color根据标准输出是否为终端,使用选项。

使用引号时,echo会提供单个参数,其中嵌入了换行符、空格,它们按原样回显到文件中。

当不使用引号时,echo会提供多个参数,这些参数由IFS. 因此 echo 将它们全部打印在一行中。但是,不要跳过这些引号......

如何修复它:

我认为,拆分总是发生在某个文件名的末尾,而不是在文件名之间。因此,这两个选项之一可能对您有用:

ls -1dmb /bin/* | tr '\n' ' ' >test
ls -1dmb /bin/* | tr -d '\n' >test
于 2014-09-05T12:04:15.767 回答
0

@anishsane 正确回答了主题问题(即ls进行包装和删除它们的方法)并涵盖了引用问题,但引用问题负责行数差异而不是ls.

这里的问题完全是引用以及命令行、回显和命令替换如何工作的问题。

的输出"$(ls ...)"是一个带有嵌入换行符的字符串,通过引号保护免受外壳程序的影响。将该值交给echo并按echo字面意思吐出(使用换行符)。

的输出$(ls ...)是一个不受 shell 保护的字符串,因此会进行分词和空白规范化。命令替换不能提前终止您的命令行(您不希望echo $(ls -1)在有两个文件的目录中运行echo first_file; second_file,对吗?)换行符作为echo. shell 然后 word 将结果拆分为空格(包括换行符),并为 echo 提供一个参数列表,在该列表中echo愉快地执行echo first_file second_file ...,您可以猜到,它只输出一行输出。

试试这个看看我的意思:

$ c() {
    printf 'argc: %s\n' "$#";
    printf 'argv: %s\n' "$@"
}
$ ls *
a.sh b.sh temp
$ ls -1dmb *
a.sh, b.sh, temp
$ c "$(ls -1dmb *)"
argc: 1
argv: a.sh, b.sh, temp
$ c $(ls -1dmb *)
argc: 3
argv: a.sh,
argv: b.sh,
argv: temp
于 2014-09-05T13:19:45.683 回答