如果任何命令返回一个非零值,则中止shell脚本?
我有一个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或者直到testing的一部分,或者是一个&&或||的一部分 名单。
有关更多详细信息,请参见“set”内部命令的bash(1)手册页 。
我个人用“set -e”启动几乎所有的shell脚本。 当一个脚本在中间失败并且对脚本的其余部分进行假设时,脚本固执地继续下去是非常烦人的。
要添加到接受的答案:
请记住, set -e
有时是不够的,特别是如果你有pipe道。
例如,假设你有这个脚本
#!/bin/bash set -e ./configure > configure.log make
…按预期工作:在configure
错误中止执行。
明天你做一个看似微不足道的变化:
#!/bin/bash set -e ./configure | tee configure.log make
…现在它不工作。 这在这里解释,并提供一个解决方法(仅Bash):
#!/斌/庆典 设置-e 设置-o pipefail ./configure | tee configure.log 使
你的例子中的if语句是不必要的。 只是这样做:
dosomething1 || exit 1
如果你采取Ville Laurikari的build议,并使用set -e
然后对于一些命令,你可能需要使用这个:
dosomething || true
|| true
|| true
将使命令pipe道有一个true
返回值,即使命令失败,所以-e
选项不会终止脚本。
如果你有清理,你需要退出,你也可以使用伪信号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选项引起的退出等)时,您的陷阱将被执行。
用-e
或者在顶部set -e
运行。
另外看看set -u
。
$?
variables是很less需要的。 伪成语command; if [ $? -eq 0 ]; then X; fi
command; if [ $? -eq 0 ]; then X; fi
command; if [ $? -eq 0 ]; then X; fi
应该总是写作, if command; then X; fi
if command; then X; fi
if command; then X; fi
。
$?
的情况 是需要的时候需要检查多个值:
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
一个expression式
dosomething1 && dosomething2 && dosomething3
当其中一个命令以非零值返回时将停止处理。 例如,下面的命令永远不会打印“完成”:
cat nosuchfile && echo "done" echo $? 1
#!/bin/bash -e
应该足够了。
只是抛出另一个参考,因为有一个额外的问题马克Edgarsinput,这是一个额外的例子,涉及整体的话题:
[[ `cmd` ]] && echo success_else_silence
这与cmd || exit errcode
相同 cmd || exit errcode
为某人显示。
例如。 我想确保一个分区被卸载如果挂载:
[[ `mount | grep /dev/sda1` ]] && umount /dev/sda1