如何在称为条件的shell函数中可靠地处理错误?

时间:2011-07-05 10:42:44

标签: bash shell error-handling

使用bash 4.1.5:

#!/bin/bash

set -e

foo()
{
        false
        echo "argh, I don't want to get there! What about set -e?!"
}

foo && echo "ok"

这会产生以下输出:

argh, I don't want to get there! What about set -e?!
ok

每当foo被称为条件时(即ifwhile&&||内等),就会出现此问题。如果被称为简单命令,foo行为正确。

我发现这种行为令人惊讶并且非常危险,因为这意味着bash函数的行为会根据其调用方式而改变。例如,即使像foofoo && true这样简单的事情也会产生相同的结果。这非常麻烦!人们只能想象如果foo做敏感操作会导致多少混乱......

我可以使用任何解决方法来避免这种情况吗?

2 个答案:

答案 0 :(得分:1)

如果失败,为什么不让foo()返回非零退出代码?

foo(){
    return 1
    echo "argh, I don't want to get here! What about set -e?!"
}

答案 1 :(得分:1)

您描述的行为是预期的,而且非常必要。考虑一下这样的函数:

word_is_in_file() {
   grep $1 $2 > /dev/null
}

现在,考虑使用此功能的脚本(对不起,这个例子有点人为 因为真正的脚本可能只是直接调用grep来做出决定:

if word_is_in_file $word $file; then
  do_something
else
  do_something_else
fi

函数的定义可以隐藏在shell库中 作者从未见过的功能。作者没有考虑 grep失败了,如果失败将会非常困惑 脚本因此而终止。

获得所需语义的方法是执行以下操作:

foo() {
   # This function will abort if errors are encountered, but 
   # the script will continue
   sh -e -c '
   false
   echo not reached'
}

foo && echo not reached
echo reached
foo
echo not reached

set -e的语义也设置为不中止脚本 出于同样的原因,“foo&& ...”案例。它允许分支。