我正在编写一个shell安装脚本
在每个命令之后我需要检查命令是否成功 - 我必须通知用户失败的原因
如果出现故障 - 安装无法继续,目前在我添加的每个命令之后
if [ $? -eq 0 ]; then
但是这为shell脚本的每个命令增加了6行 有没有办法缩短这个检查?
样品:
do some command
if [ $? -eq 0 ]; then
echo notify user OK
else
echo notify user FAIL
return -1
fi
do some command
if [ $? -eq 0 ]; then
echo notify user OK
else
echo notify user FAIL
return -1
fi
答案 0 :(得分:4)
首先,检查命令是否有效的惯用方法直接在if
语句中。
if command; then
echo notify user OK >&2
else
echo notify user FAIL >&2
return -1
fi
(良好做法:使用>&2
将消息发送给stderr。)
有几种方法可以简化这一点。
编写功能
就像在其他编程语言中一样,可以将通用逻辑转移到共享函数中。
check() {
local command=("$@")
if "${command[@]}"; then
echo notify user OK >&2
else
echo notify user FAIL >&2
exit 1
fi
}
check command1
check command2
check command3
不要打印任何内容
在惯用shell脚本中,成功的命令不会打印任何内容。什么都不打印意味着UNIX的成功。此外,任何失败的良好命令都会打印错误消息,因此您不需要添加错误消息。
利用这两个事实,只要命令失败,就可以使用|| exit
退出。您可以将||
视为"否则"。
command1 || exit
command2 || exit
command3 || exit
使用-e
或者,您可以启用-e
shell标志,以便在命令失败时退出shell。然后你根本不需要任何东西。
#!/bin/bash -e
command1
command2
command3
不要打印任何内容
如果您确实需要错误消息,但没有成功消息,则die()
功能很受欢迎。
die() {
local message=$1
echo "$message" >&2
exit 1
}
command1 || die 'command1 failed'
command2 || die 'command2 failed'
command3 || die 'command3 failed'
答案 1 :(得分:3)
这是一个代码反模式。你想要
if do some command; then
echo notify user OK
else
echo notify user fail
exit 255 # exit code must be unsigned short
fi
脚本顶部的命令set -e
将强制shell发出故障信号并在任何命令失败时退出脚本。这有一些不明显的复杂情况,但实际上可能就是你想要的。
回到前面的主题,一个共同的风格是
do some command && echo notify user OK || die 255 Notify user fail
die
的定义是easily googlable,也可能激发您探索将成功场景重构为函数的方法,以便您可以执行类似
guard "enable the frobnitz" do some command
可能guard
定义为
guard () {
local what=$1
shift
if "$@"; then
echo "$what succeeded" >&2
else
rc=$?
echo "$what failed" >&2
exit $rc
fi
}
另请注意这有多重要的改进;我们保留原始故障退出代码,并将所有诊断打印到标准错误。实际上,前面的例子也应该至少适当地做后者。
答案 2 :(得分:2)
将此添加到脚本的开头。如果任何命令返回非零状态,它将使shell停止脚本。
set -e
问候!
答案 3 :(得分:1)
我猜你可以在一个函数中移动检查逻辑,如:
checkLastCommand() {
if [ $? -eq 0 ]; then
echo notify user OK
else
echo notify user FAIL
exit -1
fi
}
do some command
checkLastCommand
do some command
checkLastCommand