退出总是被称为 - 变量优先

时间:2017-08-22 12:20:35

标签: bash

我是bash的新手,并且遇到一个问题,即在我的脚本中始终调用exit。考虑一下这个简单的代码:

if [[ "$x" -ge 1 && "$x" -le 4 ]]; then
    /export/home/scripts/script1.sh \
    "$x" \
    || echo "Error.. something went wrong." && exit 1
fi

如果&&优先于||

,我该如何处理错误?

使用GNU bash,版本3.2.51(1)。

由于

4 个答案:

答案 0 :(得分:4)

你可以这样做:

if [[ "$x" -ge 1 && "$x" -le 4 ]]; then
    /export/home/scripts/script1.sh \
    "$x" \
    || { echo "Error.. something went wrong." && exit 1 ; }
fi

注意:我使用的是{ ; },而不是(),因为()会在子shell中打开您的命令,因此它不会退出。

答案 1 :(得分:4)

&&||在shell中具有相同的优先级;隐式括号为(a || b) && c,而不是a || (b && c)。将||&&混合在同一个列表中很少是一个好主意;使用明确的if语句。

if [[ "$x" -ge 1 && "$x" -le 4 ]]; then
  if ! /export/home/scripts/script1.sh "$x"; then
      echo "Error.. something went wrong"
      exit 1
  fi
fi

对于算术比较,为了便于阅读,更喜欢arithemetic命令((...))而不是[[ ... ]]

if (( x >= 1 && x <= 4 )); then

答案 2 :(得分:2)

您可以使用大括号重新组合命令,而无需创建新的子shell:

{ true || false; } && echo true || echo false # echoes true
{ false || false; } && echo true || echo false # echoes false

它的语法非常烦人:开括号后面必须跟一个空格(或$IFS的另一个字符,如换行符或制表符),并且右括号前面必须有换行符或;,表示块的最后一个命令的结束。

括号没有那些困难,但是它们会在子shell中执行它们的指令,这会产生多种其他效果:

  • 调用exit只会退出子shell,而不是运行脚本的shell:(exit)是无操作
  • 更新变量仅适用于子shell,并且不会影响脚本已知的值:a=0;( (( a++ )) ; echo $a) ; echo $a将从子shell返回1,然后从外壳返回0。

答案 3 :(得分:0)

我更喜欢使用if对脚本进行显式测试,以便在事情变得梨形之后我可以自行清理。有助于保持代码看起来更清晰。

if [[ "$x" -ge 1 && "$x" -le 4 ]]; then
    if ! /export/home/scripts/script1.sh "$x"; then
        err="Error.. something went wrong."
        test -t 0 && echo "$err" >&2        # send errors to stderr if on terminal
        logger -p local0.critical -t $(hostname -s) "$err"       # send to syslog
        # You could even add some code here to clean up after script1.sh.
        exit 1
    fi
fi