0

我正在写一些 BASH 脚本,我希望它有一些错误处理机制:

function f()
{
  command1 || { echo "command1 failed"; return 1; }
  command2 || { echo "command2 failed"; return 1; }
  command3 || { echo "command3 failed"; return 1; }
  command4 || { echo "command4 failed"; return 1; }
}

我想通过定义一些函数来使这种重复结构更具可读性:

function print_and_return()
{
  echo "$@"
  # some way to exit the caller function
}

这样我就可以将函数编写f

function f()
{
  command1 || print_and_return "command1 failed"
  command2 || print_and_return "command2 failed"
  command3 || print_and_return "command3 failed"
  command4 || print_and_return "command4 failed"
}

实现这一目标的最佳方法是什么?谢谢。

4

3 回答 3

2

问题

你想要:

  1. 稍微完善一下您的代码。
  2. 稍微干燥一下代码。
  3. 在命令第一次失败时停止执行。

一种可能的解决方案

你可以重构你的代码。例如:

print_and_return() {
  echo "command failed: $@" >&2
  return 1
}

commands=("cmd1" "cmd2" "cmd3" "cmd4")

for cmd in "${commands[@]}"; do
    { $cmd || print_and_return "$cmd"; } || break
done
于 2012-06-16T04:48:31.923 回答
1

也许你可以使用set -e,但你必须小心,因为它退出了外壳:

function f()
{
    (
    set -e
    command1
    command2
    command3
    command4
    )
}

只要命令诊断出任何问题,当第一个命令失败时,此功能就会停止。

测试版:

function f()
{
    (
    set -e
    true
    echo true
    true
    echo true
    false
    echo false
    true
    echo true
    )
}

echo calling function
f
echo still here

输出:

calling function
true
true
still here

注意:当我使用序列时:

echo calling function
if f
then echo still here - f passed
else echo still here - f failed
fi

然后该函数在 Mac OS X 10.7.4 上的 bash 3.2.48 下表现不同:

calling function
true
true
false
true
still here - f passed

所以,有创意,但并不完全可靠。

于 2012-06-16T07:31:53.983 回答
0

类似于CodeGnome 的解决方案,但不使用数组(可能并非每个 shell 中都存在):

function callthem()
{
    for cmd; do # short form for "for cmd in "$@"; do"
        "$cmd" || { echo "$cmd failed." >&2; return 1; }
    done
}

function f()
{
    callthem command1 command2 command3 command4
    # or maybe even
    callthem command{1,2,3,4}
}
于 2012-06-16T07:14:31.057 回答