4

以下两个布尔表达式是否相同?

if [ -n $1 ] ; then   
if [ -n "$1" ] ; then

而这两个

if [ $? == 0 ] ; then
if [ "$?" == 0 ] ; then

如果不是 - 什么时候应该将变量放在引号中?

4

3 回答 3

8

当值可能包含空格或通常不是连续的字符串时,将变量放在引号中。所以

因为$?应该总是介于 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

于 2012-08-30T18:02:28.113 回答
8

使用[命令(是的,它是命令),您几乎应该总是使用引号。例外是如此罕见,我什至可能不会进入它们。例如,

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
于 2012-08-30T18:11:39.520 回答
4

它们并不总是相同的。如果所讨论的变量为空或包含空格,则[命令(别名为test)的参数可能太少或太多。

bash中,您可以使用在评估条件之前不将变量拆分为单词的内置[[ -n $1 ]]条件构造,这意味着不需要双引号。

于 2012-08-30T18:05:39.237 回答