检查bash变量是否等于0

259

我有一个bash变量depth,我想测试它是否等于0。如果是的话,我希望停止执行脚本。目前我有:

zero=0;

if [ $depth -eq $zero ]; then
    echo "false";
    exit;
fi

不幸的是,这将导致:

 [: -eq: unary operator expected

请问,我应该如何修改我的脚本让它能够正常工作?(由于翻译可能有些不准确,请见谅)

6个回答

266

看起来你的 depth 变量未设置。这意味着当Bash将变量的值代入表达式中时,表达式[ $depth -eq $zero ] 变成了 [ -eq 0 ]。问题在于,-eq 运算符错误地被用作只有一个参数(即零)的运算符,但它需要两个参数。这就是为什么会出现“一元运算符”错误消息的原因。

编辑:正如Doktor J在他对此答案的评论中提到的那样,避免检查时未设置变量的问题的一种安全方法是将变量括在""中。有关解释,请参见他的评论。

if [ "$depth" -eq "0" ]; then
   echo "false";
   exit;
fi

在使用 [ 命令时,未设置的变量在bash中会显示为空。您可以使用以下测试进行验证,所有测试都将评估为 true,因为 xyz 要么为空,要么未设置:

  • if [ -z ] ; then echo "true"; else echo "false"; fi
  • xyz=""; if [ -z "$xyz" ] ; then echo "true"; else echo "false"; fi
  • unset xyz; if [ -z "$xyz" ] ; then echo "true"; else echo "false"; fi

1
我从另一个程序中获取深度作为结果。我尝试回显它,但输出中没有任何内容。然而,当我像@Jacek Dominiak建议的那样使用[[]]时,脚本可以正常工作(如果变量确实未设置,则这是相当奇怪的)。我必须承认我真的不明白这里发生了什么... - Perlnika
7
你的深度变量未设置。这意味着Bash看到一个表达式,它说“[ -eq 0 ]; then”,这对它来说没有意义。 "[[]]"是更安全的版本,它似乎让Bash将其视为[[null -eq 0]],这是正确的。 - cyon
4
更安全的检查方式是将两边都用双引号括起来,即 if [ "$depth" -eq "0" ];这样,一个未设置的变量($depth)会被评估为 ""(当然不等于零)。 - Doktor J
1
@DoktorJ 同意,那是更好的方法。我会更新代码。 - cyon
2
这给了我一个“[:非法数字:”错误。 - Daniel Kmak
显示剩余2条评论

83

双括号(( ... ))用于算术运算。

双方括号[[ ... ]]可用于比较和检查数字(仅支持整数),以下是可用的运算符:

· NUM1 -eq NUM2 returns true if NUM1 and NUM2 are numerically equal.

· NUM1 -ne NUM2 returns true if NUM1 and NUM2 are not numerically equal.

· NUM1 -gt NUM2 returns true if NUM1 is greater than NUM2.

· NUM1 -ge NUM2 returns true if NUM1 is greater than or equal to NUM2.

· NUM1 -lt NUM2 returns true if NUM1 is less than NUM2.

· NUM1 -le NUM2 returns true if NUM1 is less than or equal to NUM2.

例如

if [[ $age > 21 ]] # bad, > is a string comparison operator

if [ $age > 21 ] # bad, > is a redirection operator

if [[ $age -gt 21 ]] # okay, but fails if $age is not numeric

if (( $age > 21 )) # best, $ on age is optional

3
你能否提供一些理由或证据,解释为什么某些方法是好的,而其他方法则不好? - Dennis
@Dennis:这个链接似乎证实了答案中所说的内容(->用于字符串与整数比较的不同括号)。 - mozzbozz
best, $ on age is optional It's not working without $ - Jean-Marc Amon
1
if (( age > 21 ))if (( $age > 21 )) 有时是不同的。您可以查看 https://github.com/koalaman/shellcheck/wiki/SC2004 - Jess Chen

26

试试:

zero=0;

if [[ $depth -eq $zero ]]; then
  echo "false";
  exit;
fi

2
双括号在表达式中保留未设置/空变量时更加智能,将其作为单独的单词处理。 - glenn jackman
@pavel,[是bash内置命令,请参见https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#Bourne-Shell-Builtins。 - Nicholas Sushkin

25

你也可以使用这种格式,并使用比较运算符如'=='和'<='。

  if (( $total == 0 )); then
      echo "No results for ${1}"
      return
  fi

8
具体来说:((depth))。例如,以下代码将打印1
declare -i x=0
((x)) && echo $x

x=1
((x)) && echo $x

3
你可以尝试这样做:
: ${depth?"Error Message"} ## when your depth variable is not even declared or is unset.

注意:在depth后面只需加上?

或者

: ${depth:?"Error Message"} ## when your depth variable is declared but is null like: "depth=". 

注意:这里在depth之后是: ?

如果变量depth的值为null,它将打印错误消息并退出。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接