在另一个问题中,我被建议“双引号 $变量”在我的脚本中以避免错误。
在阅读了大量有关双引号的信息后,我推测当我需要(例如)循环文件时,我可以/必须从双引号中排除通配符,但我想确定一下。
你能告诉我以下两种用法是否正确的使用双引号?
for file in "$workingdir"/*; do
#do something with $file
done
if [[ $workingdir == $variable* ]]; then
#do something
fi
就我在测试中看到的情况而言,使用将设置我不想要的变量"$workingdir/*"
。file
$workingdir/*
谢谢。
问候
答案1
你给出的第一个例子是正确的(假设它意味着显而易见的事情):
for file in "$workingdir"/*; do
这将遍历与变量的值相对应的目录中的文件列表workingdir
,即使其中包含空格或其他奇怪字符也能有效。
然而,第二个例子更加复杂:
if [[ $workingdir == $variable* ]]; then
在这种情况下,变量的值variable
将被视为模式,而不是固定字符串。例如,如果variable
设置为“*foo”,则如果$workingdir
其值中包含“foo”,则整体条件将匹配。如果您希望$variable
将其视为文字字符串而不是模式,则必须再次将其放在双引号中(但不是*
,假设您想要那视为通配符):
if [[ $workingdir == "$variable"* ]]; then
...坦率地说,跟踪双引号变量在哪里重要以及在哪里不重要所带来的麻烦比它的价值要多。(即,将它们放在左侧=
或==
内部是安全的[[ ]]
- 但放在右侧或内部则不行[ ]
)。所以我建议在任何地方都对它们进行双引号,这样您就不必如此紧密地跟踪:
if [[ "$workingdir" == "$variable"* ]]; then
答案2
文件名扩展完成后单词拆分(这就是双引号的含义……)。
因此,在变量替换后"$mydir"/*
扩展为,在单词拆分后扩展为 (作为单个单词),然后在文件名扩展后扩展为 。"my directory"/*
my directory/*
my directory/file1
my directory/file2