我知道在几种情况下,在 Bash 中扩展变量时不需要使用双引号,例如 inside [[...]]
,或者在变量赋值的右侧使用时。
在阅读有关引用变量的内容时,我经常听说最好在各处使用双引号,因为只有极少数情况下您不需要它们。
在什么情况下引用行为是不可取的?我不是在谈论不需要引用的情况,而是在谈论引用变量会主动阻止某些内容工作的情况。
答案1
当您希望空变量消失时不要引用(与保留为空字符串不同):
verbose=
[[ some_condition ]] && verbose=-v
# ...later...
some_program $verbose some_args
当变量包含空格分隔的参数并且您希望 shell 将它们视为单独的单词时,请勿引用
exclude_file=
[[ -s excludelist.txt ]] && exclude_file='--exclude excludelist.txt'
# ...later...
rsync -avP $exclude /path/to/source/ remote:target
一般方法始终使用双引号除非你知道为什么你不想要它们。
答案2
当我们希望 shell 认为“哦,这些都是单独的元素,而不是一个整体!”时,避免引用是可取的。这样的东西对于数组来说非常有用。
bash-4.3$ var="one two three"
bash-4.3$ arr=( $var )
bash-4.3$ for i in "${arr[@]}"; do echo "$i"; done
one
two
three
特别是,当您生成如上例所示的数组时,这非常有用。我个人在枚举 Ubuntu 工作区的实际地址时使用了这种方法(确切的术语是视口,它们使用像 X,y 这样的坐标格式,但这是完全不同的故事)。
另一种方法是当您将变量提供给另一个需要将它们作为单独的项目进行处理的命令时。比较:
bash-4.3$ bash -c 'for item; do echo $item; done' sh "$var"
one two three
bash-4.3$ bash -c 'for item; do echo $item; done' sh $var
one
two
three
为了解决评论中提到的问题,这些示例并不意味着与“意外输入”一起使用,而是用于受控环境。此外,set noglob
如果要避免全局匹配,则可以使用它,但同样,如果您要为某些字符串组合(例如桌面视口的数值)生成数组,则完全没有危险glog
。如果您正在处理实际的用户输入,则应使用引号,而这不是本问题的主题。
答案3
[] = 内置,增加可移植性
[[]] = 复合命令,增加功能
建议在创建缩进在多个平台上共享的脚本时使用单括号。