【发布时间】:2010-09-26 23:50:02
【问题描述】:
假设一个 shell 脚本(/bin/sh 或 /bin/bash)包含几个命令。如果任何命令的退出状态失败,我如何才能干净地使脚本终止?显然,可以使用 if 块和/或回调,但有没有一种更简洁、更简洁的方法?使用 && 也不是一个真正的选项,因为命令可能很长,或者脚本可能包含循环和条件等重要内容。
【问题讨论】:
假设一个 shell 脚本(/bin/sh 或 /bin/bash)包含几个命令。如果任何命令的退出状态失败,我如何才能干净地使脚本终止?显然,可以使用 if 块和/或回调,但有没有一种更简洁、更简洁的方法?使用 && 也不是一个真正的选项,因为命令可能很长,或者脚本可能包含循环和条件等重要内容。
【问题讨论】:
使用标准的sh 和bash,您可以
set -e
会的
$ help set
...
-e Exit immediately if a command exits with a non-zero status.
它也适用于zsh(据我所知)。它也应该适用于任何 Bourne shell 后代。
使用csh/tcsh,您必须使用#!/bin/csh -e 启动您的脚本
【讨论】:
也许你可以使用:
$ <any_command> || exit 1
【讨论】:
<any_command> || eval 'echo "Please ensure ..." 1>&2; exit 1' 之类的东西 注意:eval 技巧对于将 echo 和 exit 命令组合在一起而不创建 sub-shell 是必要的;使用子外壳(如果使用括号会发生这种情况)会使exit 无效。
eval 技巧。相反,使用<any_command> || { echo "Please ensure ..." 1>&2; exit; }(注意在关闭}之前需要;)。
你可以检查 $?看看最近的退出代码是什么..
例如
#!/bin/sh
# A Tidier approach
check_errs()
{
# Function. Parameter 1 is the return code
# Para. 2 is text to display on failure.
if [ "${1}" -ne "0" ]; then
echo "ERROR # ${1} : ${2}"
# as a bonus, make our script exit with the right error code.
exit ${1}
fi
}
### main script starts here ###
grep "^${1}:" /etc/passwd > /dev/null 2>&1
check_errs $? "User ${1} not found in /etc/passwd"
USERNAME=`grep "^${1}:" /etc/passwd|cut -d":" -f1`
check_errs $? "Cut returned an error"
echo "USERNAME: $USERNAME"
check_errs $? "echo returned an error - very strange!"
【讨论】: