为什么 shell printf 运行 没有被引用时串在一起?
Why does shell printf run strings together when not quoted?
有人可以解释 shell 脚本中的这种行为吗:
TESTVAR='something fishy'
echo $TESTVAR
something fishy
但是
printf "%b" $TESTVAR
somethingfishy (space removed)
同时
printf "%b" "$TESTVAR"
something fishy
为什么会这样?
此行为是两个规则的结果:
当您传递 printf
个比格式字符串包含的占位符更多的参数时,将重复格式字符串,直到使用完所有参数。对于只有一个占位符的格式字符串,这意味着它在每个后续参数中重复一次。
当您不引用参数扩展时,它们会经历 word-splitting(为 IFS
中每个字符两侧的内容创建一个单独的词)和 glob 扩展 (如果存在任何此类名称,则将这些单词替换为它们在解释为 glob 时匹配的文件名列表),从而导致可变数量的 shell 个单词,每个单词都作为单独的参数传递给 printf
.
因此,具有默认值 IFS
的 TESTVAR='something fishy'; echo $TESTVAR
精确等价于 echo "something" "fishy"
,它打印 something fishy
,因为 echo
分隔每个参数space.
相比之下,printf %b $TESTVAR
变为printf %b "something" "fishy"
,它使用%b
格式化something
,并再次格式化fishy
;那里没有插入 space,因此您不会在输出中得到任何 space。 (相反,如果你做到了 printf '%b ' $TESTVAR
,你会看到插入了 space)。
最后,printf %b "$TESTVAR"
运行 printf %b "something fishy"
; space 被保留,因为它是第三个参数的文字部分,因此 %b
格式字符串只被评估一次,针对整个 something fishy
参数已经包含 space .
这个故事的教训:总是引用你的扩展。另见 BashPitfalls #14 详细描述 echo $foo
本身是错误的,除非引用为 echo "$foo"
.
有人可以解释 shell 脚本中的这种行为吗:
TESTVAR='something fishy'
echo $TESTVAR
something fishy
但是
printf "%b" $TESTVAR
somethingfishy (space removed)
同时
printf "%b" "$TESTVAR"
something fishy
为什么会这样?
此行为是两个规则的结果:
当您传递
printf
个比格式字符串包含的占位符更多的参数时,将重复格式字符串,直到使用完所有参数。对于只有一个占位符的格式字符串,这意味着它在每个后续参数中重复一次。当您不引用参数扩展时,它们会经历 word-splitting(为
IFS
中每个字符两侧的内容创建一个单独的词)和 glob 扩展 (如果存在任何此类名称,则将这些单词替换为它们在解释为 glob 时匹配的文件名列表),从而导致可变数量的 shell 个单词,每个单词都作为单独的参数传递给printf
.
因此,具有默认值 IFS
的 TESTVAR='something fishy'; echo $TESTVAR
精确等价于 echo "something" "fishy"
,它打印 something fishy
,因为 echo
分隔每个参数space.
相比之下,printf %b $TESTVAR
变为printf %b "something" "fishy"
,它使用%b
格式化something
,并再次格式化fishy
;那里没有插入 space,因此您不会在输出中得到任何 space。 (相反,如果你做到了 printf '%b ' $TESTVAR
,你会看到插入了 space)。
最后,printf %b "$TESTVAR"
运行 printf %b "something fishy"
; space 被保留,因为它是第三个参数的文字部分,因此 %b
格式字符串只被评估一次,针对整个 something fishy
参数已经包含 space .
这个故事的教训:总是引用你的扩展。另见 BashPitfalls #14 详细描述 echo $foo
本身是错误的,除非引用为 echo "$foo"
.