我更喜欢编写可靠的shell代码,因此总是设置errexit和nounset.
以下代码将在bad_command行停止
#!/bin/bash
set -o errexit ; set -o nounset
bad_command # stop here
good_command
Run Code Online (Sandbox Code Playgroud)
我想抓住它,这是我的方法
#!/bin/bash
set -o errexit ; set -o nounset
rc=1
bad_command && rc=0 # stop here
[ $rc -ne 0 ] && do_err_handle
good_command
Run Code Online (Sandbox Code Playgroud)
有没有更好或更清洁的方法
我的答案:
#!/bin/bash
set -o errexit ; set -o nounset
if ! bad_command ; then
# error handle here
fi
good_command
Run Code Online (Sandbox Code Playgroud)
rra*_*nza 42
这个怎么样?如果你想要实际的退出代码......
#!/bin/sh
set -e
cat /tmp/doesnotexist && rc=$? || rc=$?
echo exitcode: $rc
cat /dev/null && rc=$? || rc=$?
echo exitcode: $rc
Run Code Online (Sandbox Code Playgroud)
输出:
cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0
Run Code Online (Sandbox Code Playgroud)
小智 18
继续使用errexit.它可以帮助查找可能具有不可预测(并且难以检测)结果的错误.
#!/bin/bash
set -o errexit ; set -o nounset
bad_command || do_err_handle
good_command
Run Code Online (Sandbox Code Playgroud)
以上工作正常.errexit只需要线路通过,就像你做的那样bad_command && rc=0.因此,上面带有'或'只会在bad_command失败的情况下运行do_err_handle ,并且只要do_err_handle也不会'失败',那么脚本将继续.
继续编写可靠的 shell 代码。
如果 bad_command 确实是一个命令,那么你就做对了。但要小心 if、while、||、&& 或 ! 中的函数调用,因为 errexit 在那里不起作用。这可能很危险。
如果你的 bad_command 实际上是 bad_function 你应该这样写:
set -eu
get_exit_code() {
set +e
( set -e;
"$@"
)
exit_code=$?
set -e
}
...
get_exit_code bad_function
if [ "$exit_code" != 0 ]; then
do_err_handle
fi
Run Code Online (Sandbox Code Playgroud)
这在 bash 4.0 中运行良好。在 bash 4.2 中,您只能获得退出代码 0 或 1。
更新:bash 5.0 中的退出代码没有问题。
@rrauenza 给出的答案略有不同。由于&& rc=$?部分是他们的答案将始终等于&& rc=01 也可以在运行命令之前设置rc为0。在我看来,结果最终更具可读性,因为变量是在它自己的代码行中预先定义的,并且只有在命令以非零退出状态退出时才会更改。如果nounset也给出了,那么现在很明显,rc确实从未未定义。这也避免了混合&&和||在同一行中,这可能会令人困惑,因为人们可能并不总是牢记运算符的优先级。
#!/bin/sh
set -eu
rc=0
cat /tmp/doesnotexist || rc=$?
echo exitcode: $rc
rc=0
cat /dev/null || rc=$?
echo exitcode: $rc
Run Code Online (Sandbox Code Playgroud)
输出:
cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0
Run Code Online (Sandbox Code Playgroud)