什么时候应该在布尔条件中用引号推variables?

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

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

而这两个

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

如果没有 – 什么时候应该把variables放在引号中?

在有可能包含空格的情况下将变量放在引号中,或者通常不是连续的字符串。 所以

作为$? 应该始终是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 -zb' if [ -n $1 ]; then echo foo; fi # … crickets if [ -n "$1" ]; then echo foo; fi foo 

Bash也有[[关键字(是的,这是一个关键字),这是聪明的足够了解扩展,避免陷阱的不引用。 (但是在[[表达式中)引用通常是安全的。

由于[命令是POSIX兼容的[[是一个bashism,你决定何时使用哪个。

至于你的第二个例子,如果你正在比较某个数字,使用==是一个双数。 如果你正在写bash,使用一个算术表达式,比如

 if (( $? == 0 )); then … 

但是,如果你正在尝试POSIX合规性,请写下来

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

通常,直接比较$? 是一个红旗,因为比较一个命令的成功或失败正好是if

 if somecommand; then … 

比…更好

 somecommand if (( $? == 0 )); then … 

但是,如果你确实需要使用它, $? 是一个例外,因为它保证只有一个单字节的无符号整数,所以使用不加引号是很安全的,尽管它不会引起报价。

 $ 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 

它们并不总是一样的。 如果所讨论的变量为空或者包含空格,那么[ command( test别名)可以有太多或者太多的参数。

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