我一直在写一些shell脚本,如果有能力停止所述shell脚本的执行,如果任何命令失败,我会发现它很有用。请看下面的例子:

#!/bin/bash

cd some_dir

./configure --some-flags

make

make install

因此,在这种情况下,如果脚本不能更改到指定的目录,那么如果失败,它肯定不想在之后执行./configure。

现在我很清楚,我可以对每个命令进行if检查(我认为这是一个无望的解决方案),但是是否存在一个全局设置,以便在其中一个命令失败时使脚本退出?


当前回答

要在命令失败时立即退出脚本,请在开头添加以下内容:

set -e

这将导致脚本在不属于某些测试的命令(如if[…]]条件或&&构造)退出,退出代码为非零。

其他回答

我认为你要找的是trap命令:

trap command signal [signal ...]

欲了解更多信息,请参阅本页。

另一种选择是在脚本顶部使用set -e命令——如果任何程序/命令返回非真值,它将使脚本退出。

以下是如何做到这一点:

#!/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 *** 
************
'

使用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(用于选项)pipefail在命令管道失败时退出。这里详细记录了一些陷阱和变通方法。

(*)注:

命令的一部分,如果失败的命令,则shell不退出 命令列表紧跟在while或until关键字之后, 部分测试后跟if或elif保留字,部分 在&&或||列表中执行的任何命令的 在最后的&&或||之后,管道中的任何命令 最后一个,或者命令的返回值与 !

(摘自man bash)

一个成语是:

cd some_dir && ./configure --some-flags && make && make install

我知道这可能会很长,但对于较大的脚本,您可以将其分解为逻辑函数。

另一种适合第一行的可接受的答案:

#!/bin/bash -e

cd some_dir  

./configure --some-flags  

make  

make install