如果任何命令返回非零值,则中止 shell 脚本
- 2024-10-09 09:10:00
- admin 原创
- 96
问题描述:
我有一个 Bash shell 脚本,可以调用许多命令。
如果任何命令返回非零值,我希望 shell 脚本自动退出并返回值 1。
如果不明确检查每个命令的结果,这可能吗?
例如,
dosomething1
if [[ $? -ne 0 ]]; then
exit 1
fi
dosomething2
if [[ $? -ne 0 ]]; then
exit 1
fi
解决方案 1:
将其添加到脚本的开头:
set -e
如果简单命令以非零退出值退出,这将导致 shell 立即退出。简单命令是指不属于if
、while
或until
测试或&&
或||
列表的任何命令。
有关更多详细信息,请参阅bash 手册中的“set”内部命令。
如果脚本在中间出现故障并破坏了其余脚本的假设,而脚本却顽固地继续运行,这真的很烦人。我个人几乎用 来启动所有可移植的 shell 脚本set -e
。
如果我专门使用bash,我会从
set -Eeuo pipefail
这涵盖了更多类似方式的错误处理。我认为这些是新 bash 程序的合理默认值。有关这些选项的更多信息,请参阅 bash 手册。
解决方案 2:
添加到已接受的答案:
请记住,set -e
有时这还不够,特别是当您有管道时。
例如,假设你有这个脚本
#!/bin/bash
set -e
./configure > configure.log
make
...其工作符合预期:错误导致configure
中止执行。
明天你做一个看似微不足道的改变:
#!/bin/bash
set -e
./configure | tee configure.log
make
...现在它不起作用了。 此处对此进行了解释,并提供了一种解决方法(仅限 Bash):
/bin/bash #!/bin/bash
设置-e
设置-o pipefail
./configure | tee configure.log
制作
解决方案 3:
您的示例中的 if 语句是不必要的。只需这样做:
dosomething1 || exit 1
如果您听取 Ville Laurikari 的建议并使用set -e
某些命令,您可能需要使用以下命令:
dosomething || true
即使命令失败,也会使命令管道具有返回值,因此该选项|| true
不会终止脚本。true
`-e`
解决方案 4:
如果您需要在退出时进行清理,也可以使用带有伪信号 ERR 的“trap”。这与捕获 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 选项导致的退出等,您的陷阱将被执行。
解决方案 5:
变量$?
很少需要。伪习语command; if [ $? -eq 0 ]; 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
解决方案 6:
-e
与或set -e
在顶部一起运行它。
也看一下set -u
。
解决方案 7:
出现错误时,以下脚本将打印一条带有失败命令的红色错误消息,然后退出。
将其放在 bash 脚本的顶部:
# BASH error handling:
# exit on command failure
set -e
# keep track of the last executed command
trap 'LAST_COMMAND=$CURRENT_COMMAND; CURRENT_COMMAND=$BASH_COMMAND' DEBUG
# on error: print the failed command
trap 'ERROR_CODE=$?; FAILED_COMMAND=$LAST_COMMAND; tput setaf 1; echo "ERROR: command \"$FAILED_COMMAND\" failed with exit code $ERROR_CODE"; put sgr0;' ERR INT TERM
解决方案 8:
#!/bin/bash -e
就足够了。
解决方案 9:
类似这样的表达
dosomething1 && dosomething2 && dosomething3
当其中一个命令返回非零值时,将停止处理。例如,以下命令永远不会打印“done”:
cat nosuchfile && echo "done"
echo $?
1
解决方案 10:
我只是再举一个例子作为参考,因为对 Mark Edgars 的输入还有一个额外的问题,下面是一个额外的例子,并涉及到整个主题:
[[ `cmd` ]] && echo success_else_silence
这与某人展示的相同cmd || exit errcode
。
例如,我想确保已安装的分区已被卸载:
[[ `mount | grep /dev/sda1` ]] && umount /dev/sda1
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件