以下两个布尔表达式是否相同?
if [ -n $1 ] ; then
if [ -n "$1" ] ; then
而这两个
if [ $? == 0 ] ; then
if [ "$?" == 0 ] ; then
如果不是 - 什么时候应该将变量放在引号中?
当值可能包含空格或通常不是连续的字符串时,将变量放在引号中。所以
因为$?
应该总是介于 0 和 255 之间,你不需要引用它,因为它是每个子流程返回后设置的返回值。不可能通过直接分配字符串值来打破它,即
$?=Is of course wrong and should be
?=Bad value assigment
因为用户变量名称必须以 [A-Za-z_] 开头,所以不要那样做;-)
而对于 1 美元,如果传入一个值
myscript "arg1 with spaces"
考试
if [ -n $1 ] ; then
会爆炸,
但测试
if [ -n "$1" ] ; then
将会成功。
IHTH
使用[
命令(是的,它是命令),您几乎应该总是使用引号。例外是如此罕见,我什至可能不会进入它们。例如,
set -- 'x -a -z b'
if [ -n $1 ]; then echo foo; fi
# … crickets
if [ -n "$1" ]; then echo foo; fi
foo
Bash 也有[[
关键字(是的,它是关键字),它足够聪明,可以了解扩展并避免不引用的陷阱。(但在[[
表达式中引用通常仍然是安全的。)
由于该[
命令符合 POSIX 并且[[
是一个 bashism,因此您决定何时使用哪个。
至于您的第二个示例,如果您将某物与数字进行比较,则 using==
是一种bashism。如果您正在编写 bash,请使用算术表达式,例如
if (( $? == 0 )); then …
但是,如果您正在尝试 POSIX 合规性,请编写它
if [ "$?" = 0 ]; then …
通常,直接比较$?
是一个危险信号,因为比较命令的成功/失败正是这样if
做的:
if somecommand; then …
好于
somecommand
if (( $? == 0 )); then …
但是如果你确实需要使用它,$?
这是一个例外,因为它保证永远只是一个单字节无符号整数,所以使用 unquoted 是非常安全的,尽管引用它并没有什么坏处。
$ false; if [ $? = 0 ]; then echo t; else echo f; fi
f
$ true; if [ $? = 0 ]; then echo t; else echo f; fi
t
$ false; if [ "$?" = 0 ]; then echo t; else echo f; fi
f
$ true; if [ "$?" = 0 ]; then echo t; else echo f; fi
t
$ false; if [ $? == 0 ]; then echo t; else echo f; fi
f
$ true; if [ $? == 0 ]; then echo t; else echo f; fi
t
$ false; if [ "$?" == 0 ]; then echo t; else echo f; fi
f
$ true; if [ "$?" == 0 ]; then echo t; else echo f; fi
t
它们并不总是相同的。如果所讨论的变量为空或包含空格,则[
命令(别名为test
)的参数可能太少或太多。
在bash
中,您可以使用在评估条件之前不将变量拆分为单词的内置[[ -n $1 ]]
条件构造,这意味着不需要双引号。