我有以下示例:
$ a="$(ls)"
$ echo $a
backups cache crash lib local lock log mail opt run snap spool tmp
$
$ echo "$a"
backups
cache
crash
lib
local
lock
log
mail
opt
run
snap
spool
tmp
现在有了printf
:
$ printf $a
backups
$
$ printf "$a"
backups
cache
crash
lib
local
lock
log
mail
opt
run
snap
spool
tmp
为什么输出如此不同?在这种情况下,引号会做什么?有人可以解释这里发生了什么吗?
PS 找到了一些关于该ls
行为的解释:
ls 的输出有换行符,但显示在单行上。为什么?
https://superuser.com/questions/424246/what-is-the-magic-separator-between-filenames-in-ls-output
http://mywiki.wooledge.org/ParsingLs
换行符可以这样检查:
ls | od -c
echo $a
是相同的而
echo "$a"
与请参阅https://mywiki.wooledge.org/Quotes。
for 的第一个参数
printf
是一个格式化字符串,与它使用字符串作为格式并丢弃其余参数printf $a
相同,因为在格式化字符串中没有任何东西可以使用它们。就像:printf backups cache crash lib local lock log mail opt run snap spool tmp
backups
%s
不要
a="$(ls)"
尝试创建一个包含文件名的标量变量,因为这很脆弱,a=(*)
而是将它们保存在一个数组中。感谢@Ed Morton 和@Kusalananda 的解释。
我想我的问题是我一直认为默认情况下
ls
使用空格或制表符拆分文件。但事实上,结果证明它用换行符分隔它们,但在打印到终端时将文件输出为列(垂直排序)。换行符可以通过以下方式检查:我会将@Kusalananda 的答案从评论部分移到答案中,因为它很有帮助:
简而言之,
echo
输出它的参数,它们之间有空格。这就是这样echo
做的。使用
echo $a
时,shell 会$a
根据空格、制表符和换行符将 的内容拆分为几个参数(然后还会对每个生成的单词进行文件名通配)。echo
然后用它们之间的空格打印它们。使用
echo "$a"
,您只能给 echo 一个参数。该字符串"$a"
包含来自 的输出的换行符ls
,这些换行符由 保留和输出echo
。