回音和引号有什么作用?

时间:2014-11-10 03:02:38

标签: bash

nkcoder@nkcoder:bash$ ls
doublebracket.sh  for.sh  if.sh  quote.sh  singlebracket.sh  test.sh
nkcoder@nkcoder:bash$ ls | wc -l
6
nkcoder@nkcoder:bash$ echo $(ls)
doublebracket.sh for.sh if.sh quote.sh singlebracket.sh test.sh
nkcoder@nkcoder:bash$ echo $(ls) | wc -l
1
nkcoder@nkcoder:bash$ echo "$(ls)"
doublebracket.sh
for.sh
if.sh
quote.sh
singlebracket.sh
test.sh
nkcoder@nkcoder:bash$ echo "$(ls)" | wc -l
6
  1. ls的输出是6行,换行符在哪里?
  2. 为什么引号在使用" $(ls)"时会影响结果?
  3. 我真的很困惑,有人可以帮忙提供一些解释吗?非常感谢。

3 个答案:

答案 0 :(得分:2)

在bash中,所有不带引号的参数(包括由命令替换生成的参数(``或$()))组合成一行。使用引号使参数(命令替换输出)保持其原始形式,因此保留换行符。

要查看差异,您可以运行:

function three_lines()
{
    echo one; echo two; echo three
}
$ three_lines
one
two
three
$ echo `three_lines`
one two three
$ echo "`three_lines`"
one
two
three

答案 1 :(得分:1)

在我阅读时,这里有多个问题:


为什么ls | wc -l报告的输出行数不同于手动运行ls的输出行数?

ls检查其标准输出是否为TTY - 同样检查您自己的脚本可以对[[ -t 1 ]]进行检查。如果该测试返回true,则默认情况下将其输出修改为每个文件一行。


为什么echo $(ls)echo "$(ls)"不同?

如果未引用扩展,则扩展的输出(例如$(ls)$foo word-split

分词发生在shell变量IFS中的字符上,或者 - 默认情况下 - 空格字符,制表符和换行符。

然后将该拆分的结果替换为正在运行的命令的单个参数。所以:

$ rm -rf tmp.d && mkdir -p tmp.d && cd tmp.d && touch "hello cruel" world
$ echo $(ls)

...将首先运行ls。因为输出不是TTY,ls的输出如下所示:

hello cruel
world

但是,因为扩展不在引号内,所以shell会将该块拆分为单词。因为默认情况下换行符和空格字符都在IFS中,所以hello cruel是单个文件名的事实将丢失。因此,我们运行:

$ echo "hello" "cruel" "world"

相比之下,如果你跑:

$ echo "$(ls)"

...然后shell不会在空格上进行字符串拆分,因此它会调用:

$ echo 'hello cruel
world'

请注意,如果您真的要迭代文件,则根本不应该使用ls。见Why you shouldn't parse the output of ls(1)

答案 2 :(得分:0)

双引号将保留ls命令到echo命令的空格和新行,这就是当你使用双引号时你得到实际计数而不是使用引号的原因。 / p>

# echo hai\
> bye
haibye
# echo "hai
> bye"
hai
bye