我有一个Bash shell脚本,它调用许多命令。
如果任何命令返回非零值,我想让shell脚本自动退出并返回值为1。
如果不显式地检查每个命令的结果,这可能吗?
例如,
dosomething1
if [[ $? -ne 0 ]]; then
exit 1
fi
dosomething2
if [[ $? -ne 0 ]]; then
exit 1
fi
我有一个Bash shell脚本,它调用许多命令。
如果任何命令返回非零值,我想让shell脚本自动退出并返回值为1。
如果不显式地检查每个命令的结果,这可能吗?
例如,
dosomething1
if [[ $? -ne 0 ]]; then
exit 1
fi
dosomething2
if [[ $? -ne 0 ]]; then
exit 1
fi
当前回答
将以下内容添加到脚本开头:
set -e
如果一个简单的命令退出时退出值非零,这将导致shell立即退出。简单命令是指不属于if、while、until test或&&或||列表的任何命令。
有关“set”内部命令的详细信息,请参阅bash手册。
当某个脚本在中间发生故障并打破了对脚本其余部分的假设时,让脚本固执地继续下去是非常令人恼火的。我个人使用set -e启动几乎所有可移植shell脚本。
如果我专门处理bash,我会从
set -Eeuo pipefail
这以类似的方式涵盖了更多的错误处理。我认为这些是新的bash程序的正常默认值。有关这些选项的功能的更多信息,请参阅bash手册。
其他回答
如果你需要在退出时进行清理,你也可以使用'trap'和伪信号ERR。这与捕获INT或任何其他信号的方式相同;如果任何命令以非零值退出,bash将抛出ERR:
# Create the trap with
# trap COMMAND SIGNAME [SIGNAME2 SIGNAME3...]
trap "rm -f /tmp/$MYTMPFILE; exit 1" ERR INT TERM
command1
command2
command3
# Partially turn off the trap.
trap - ERR
# Now a control-C will still cause cleanup, but
# a nonzero exit code won't:
ps aux | grep blahblahblah
或者,特别是当你使用"set -e"时,你可以捕获EXIT;然后,当脚本因为任何原因退出时,包括正常结束、中断、由-e选项导致的退出等等,都会执行陷阱。
将以下内容添加到脚本开头:
set -e
如果一个简单的命令退出时退出值非零,这将导致shell立即退出。简单命令是指不属于if、while、until test或&&或||列表的任何命令。
有关“set”内部命令的详细信息,请参阅bash手册。
当某个脚本在中间发生故障并打破了对脚本其余部分的假设时,让脚本固执地继续下去是非常令人恼火的。我个人使用set -e启动几乎所有可移植shell脚本。
如果我专门处理bash,我会从
set -Eeuo pipefail
这以类似的方式涵盖了更多的错误处理。我认为这些是新的bash程序的正常默认值。有关这些选项的功能的更多信息,请参阅bash手册。
美元吗?很少需要变量。伪成语命令;如果[$?-eq 0];那么X;Fi应该总是写成command;那么X;fi。
$?Is required是指需要检查多个值:
command
case $? in
(0) X;;
(1) Y;;
(2) Z;;
esac
或者什么时候$?需要重用或以其他方式操作:
if command; then
echo "command successful" >&2
else
ret=$?
echo "command failed with exit code $ret" >&2
exit $ret
fi
对已接受的答案补充:
请记住,set -e有时是不够的,特别是如果你有管道。
例如,假设您有这个脚本
#!/bin/bash
set -e
./configure > configure.log
make
... 按预期工作:配置中的错误将中止执行。
明天你要做一个看似微不足道的改变:
#!/bin/bash
set -e
./configure | tee configure.log
make
... 但现在它不管用了。这里解释了这一点,并提供了一个解决方案(仅Bash):
#!/bin/bash set -e set -o pipefail ./configure | tee configure.log make
示例中的if语句是不必要的。就像这样做:
dosomething1 || exit 1
如果你采纳了Ville Laurikari的建议并使用set -e,那么对于某些命令你可能需要使用这个:
dosomething || true
|| true将使命令管道即使在命令失败时也具有真实的返回值,因此-e选项不会终止脚本。