Shell:测试 -n/-z 上只有双引号?

Shell:测试 -n/-z 上只有双引号?

例如,如果是test -e

VAR="<this is a file path: /path/to/file/or/dir"
test -e $VAR && do_something || do_anotherthing

问题:我应该"$VAR"在这里使用吗?如果没有必要,这里我不喜欢冗长,因为$VAR显然在这种情况下是一个路径,那么如果它是空字符串,它应该总是失败,因为没有路径是空字符串,然后按照我的逻辑,双引号是没有必要的。

但它是字符串测试的情况,测试 -n 例如:

VAR="<this is a string"
test -n $VAR && do_something || do_anotherthing

然后按照我的逻辑,$VAR应该放在双引号中:"$VAR"因为它可以扩展为空字符串,如果不在双引号中,则将仅扩展为-n参数并且始终为真。

因此,真正的问题是因为我怀疑我们是否应该在测试命令中仅在字符串-n-z字符串中使用双引号?

答案1

一般规则是对任何变量加双引号,除非您希望 shell 对其内容执行标记拆分和通配符扩展。

因为$VAR显然在这种情况下是一条路径,那么如果它是空字符串,它应该总是失败 [...] 然后根据我的逻辑,双引号是没有必要的。

恰恰相反。没有操作数的行为test -e是在这种特殊情况下应该引用变量的另一个原因:

$ unset foo      # or foo=""
$ test -e $foo   # note this is equivalent to `test -e'
$ echo $?
0
$ test -e "$foo"
$ echo $?
1
$

答案2

本次问答,格雷格的维基手册以获得解释。 tl;dr:它是如何工作的并不明显,您应该使用更多引用™。或者换句话说:如果您的目标是正确性和可维护性,那么正确引用大约是优先级 5(在学习了编写正确且简洁的 shell 脚本所需的所有其他奇怪之处之后),而保存单个字符的优先级是 999,999+。

答案3

这样会更好、更清晰:

if [[ "$VAR" ]]; then
    do_something
else
    do_anotherthing
fi

相关内容