我正在尝试在循环中调用一个函数,并在它抛出时优雅地处理并继续。
如果我省略 || handle_error
它只是像预期的那样停止整个脚本。
如果我离开|| handle_error
它会在错误后打印 foo is fine
并且根本不会执行 handle_error
。这也是预期的行为,它就是这样工作的。
#!/bin/bash
set -e
things=(foo bar)
function do_something {
echo "param: $1"
# just throw on first loop run
# this statement is just a way to selectively throw
# not part of a real use case scenario where the command(s)
# may or may not throw
if [[ $1 == "foo" ]]; then
throw_error
fi
# this line should not be executed when $1 is "foo"
echo "$1 is fine."
}
function handle_error {
echo "$1 failed."
}
for thing in ${things[@]}; do
do_something $thing || handle_error $thing
done
echo "done"
产量
param: foo
./test.sh: line 12: throw_error: command not found
foo is fine.
param: bar
bar is fine.
done
我想要的是
param: foo
./test.sh: line 12: throw_error: command not found
foo failed.
param: bar
bar is fine.
done
编辑:
do_something
实际上不需要返回任何东西。这只是一个抛出函数的示例,我可能会从示例源代码中删除它,因为我无法控制它的内容,我也不想控制它,并且测试其中的每个命令是否失败是不可行的。
编辑:
您不能触及do_something
逻辑。我之前说过,它只是一个包含一组可能会抛出错误的指令的函数。可能是笔误,可能是make
在CI环境下失败,也可能是网络错误。
最佳答案
我找到的解决方案是将函数保存在单独的文件中并在子shell中执行。缺点是我们失去了所有本地人。
do-something.sh
#!/bin/bash
set -e
echo "param: $1"
if [[ $1 == "foo" ]]; then
throw_error
fi
echo "$1 is fine."
我的脚本.sh
#!/bin/bash
set -e
things=(foo bar)
function handle_error {
echo "$1 failed."
}
for thing in "${things[@]}"; do
./do-something.sh "$thing" || handle_error "$thing"
done
echo "done"
产量
param: foo
./do-something.sh: line 8: throw_error: command not found
foo failed.
param: bar
bar is fine.
done
如果有更优雅的方法,我会将其标记为正确答案。将在 48 小时内再次检查。
编辑
感谢@PeterCordes 的评论和 this other answer我找到了另一种不需要单独文件的解决方案。
#!/bin/bash
set -e
things=(foo bar)
function do_something {
echo "param: $1"
if [[ $1 == "foo" ]]; then
throw_error
fi
echo "$1 is fine."
}
function handle_error {
echo "$1 failed with code: $2"
}
for thing in "${things[@]}"; do
set +e; (set -e; do_something "$thing"); error=$?; set -e
((error)) && handle_error "$thing" $error
done
echo "done"
正确产生
param: foo
./test.sh: line 11: throw_error: command not found
foo failed with code: 127
param: bar
bar is fine.
done
关于bash:错误处理和函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33704036/