我有一个非常简单的目录,其中包含"directory1"和"file2".后
out=`ls`
Run Code Online (Sandbox Code Playgroud)
我想打印我的变量:echo $out给:
directory1 file2
Run Code Online (Sandbox Code Playgroud)
但echo "$out"给出:
directory1
file2
Run Code Online (Sandbox Code Playgroud)
所以使用引号给出了每个记录在单独行上的输出.正如我们所知,ls命令打印输出使用单行表示所有文件/目录(如果行足够大以包含输出),所以我希望使用双引号可以防止我的shell将单词拆分为单独的行,而省略引号则会拆分它们.请告诉我:为什么使用引号(用于防止分词)突然分裂输出?
lsls默认情况下,当输出到TTY时,只在一行上打印多个文件名.当输出到管道,文件或类似文件时,默认是将一行打印到文件.
引用POSIX标准ls,重点补充:
默认格式是每行列出一个条目到标准输出; 例外情况是终端或指定-C,-m或-x选项之一时.如果输出是终端,则格式是实现定义的.
这是将命令分成单独的参数的行为,导致它被放在一行!在本地,您的值跨越多行,因此未经修改地回显它(没有任何拆分)以这种方式打印它.
您的命令结果如下:
out='directory1
file2'
Run Code Online (Sandbox Code Playgroud)
运行时echo "$out",会打印出确切的内容.echo $out相反,当你跑步时,行为类似于:
echo "directory1" "file2"
Run Code Online (Sandbox Code Playgroud)
...因为字符串被分成两个元素,每个元素都作为完全不同的参数传递echo,以便echo在它看来合适时处理 - 在这种情况下,在同一行上打印这两个参数.
分词可能看起来像你想要的那样,但通常情况并非如此!考虑一些特殊问题:
*空格包围,*则会被当前目录中的文件列表替换,从而导致重复的结果.请参阅为什么不应该解析输出ls.简而言之 - 在您的示例中out=`ls`,out变量(作为字符串)无法以有用,可解析的方式存储所有可能的文件名.
例如,考虑一个这样创建的文件:
touch $'hello\nworld"three words here"'
Run Code Online (Sandbox Code Playgroud)
...该文件名包含空格和换行符,并且分词将无法在输出中正确地将其检测为单个名称ls.但是,您可以在数组中存储和处理它:
# create an array of filenames
names=( * )
if ! [[ -e $names || -L $names ]]; then # this tests only the FIRST name
echo "No names matched" >&2 # ...but that's good enough.
else
echo "Found ${#files[@]} files" # print number of filenames
printf '- %q\n' "${names[@]}"
fi
Run Code Online (Sandbox Code Playgroud)