我一直在写一些 shell 脚本,如果在任何命令失败的情况下能够停止执行该 shell 脚本,我会发现它很有用。参见以下示例:
#!/bin/bash
cd some_dir
./configure --some-flags
make
make install
因此,在这种情况下,如果脚本无法更改到指示的目录,则如果脚本失败,则肯定不会在之后执行./configure。
现在,我很清楚,我可以对每个命令进行 if 检查(我认为这是一个绝望的解决方案),但是如果其中一个命令失败,是否有全局设置可以退出脚本?
使用内置set -e
#!/bin/bash
set -e
# Any subsequent(*) commands which fail will cause the shell script to exit immediately
或者,您可以在命令行上-e
bash -e my_script.sh
您也可以set +e
禁用此行为。
您可能还希望使用-e
-u
-x
和-o pipefail
选项的全部或部分,如下所示:
set -euxo pipefail
-e
在错误时退出, -u
错误在未定义变量上-o (for option) pipefail
在命令管道失败时退出。在这里很好地记录了一些陷阱和解决方法。
(*) 笔记:
壳不退出如果失败的命令是紧跟在同时或直到关键字,测试的部分继如果或elif 的保留字的命令列表的一部分,在一个执行的任何命令或&&的一部分||列表,最后一个&&或|| 之后的命令除外,管道中除最后一条命令外的任何命令,或者该命令的返回值正被!反转。
(来自man bash
)
要在其中一个命令失败后立即退出脚本,请在开头添加以下内容:
set -e
当不属于某些测试的某些命令(例如,在if [ ... ]
条件或&&
构造中)不使用非零退出代码退出时,这将导致脚本立即退出。
这是操作方法:
#!/bin/sh
abort()
{
echo >&2 '
***************
*** ABORTED ***
***************
'
echo "An error occurred. Exiting..." >&2
exit 1
}
trap 'abort' 0
set -e
# Add your script below....
# If an error occurs, the abort() function will be called.
#----------------------------------------------------------
# ===> Your script goes here
# Done!
trap : 0
echo >&2 '
************
*** DONE ***
************
'