出错时自动退出bash shell脚本

Automatic exit from bash shell script on error

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

1
2
3
4
5
6
7
8
9
#!/bin/bash  

cd some_dir  

./configure --some-flags  

make  

make install

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

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


使用set -ebuiltin:theP></

1
2
3
#!/bin/bash
set -e
# Any subsequent(*) commands which fail will cause the shell script to exit immediately

alternatively,你可以通命令行:-eon theP></

1
bash -e my_script.sh

You can also this with set +edisable的行为。P></

注:(*)P></

The shell does not exit if the command that fails is part of the
command list immediately following a while or until keyword,
part of the test following the if or elif reserved words, part
of any command executed in a && or || list except the command
following the final && or ||, any command in a pipeline but
the last, or if the command's return value is being inverted with
!

(man bashfrom)P></


当退出脚本to the one of the命令failed,add this at the beginning:P></

1
set -e

this to the exit脚本的原因立即命令that is not when some part of some试验(在if [ ... ]condition or a类&&exits construct)与非零退出队列。P></


恩:这里is how to doP></

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/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 ***
************
'


在与pipefailconjunction使用它。P></

1
2
set -e
set -o pipefail

这(errexit):中止脚本在第一误差,当在命令行exits与非零状态(除了在"if或while循环列表,在线测试,constructs)P></

原因:在管道或pipefail to the Return of the last命令的退出状态,在管在非零返回value returned。P></

和33。期权P></


to the accepted that an备选答案:在第一线上的FITSP></

1
2
3
4
5
6
7
8
9
#!/bin/bash -e

cd some_dir  

./configure --some-flags  

make  

make install


一idiom is:P></

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

that can get龙明白这些,但你可以打破它scripts for空气日期2010年1月17一逻辑函数。P></


我认为你是什么looking for that is the trap命令:P></

1
trap command signal [signal ...]

为更多的信息,see this page。P></

another option to the set -eis at the command使用顶部的脚本将让你的脚本/程序/ if any the exit命令值不返回True。P></


the existing错过一点在回答inherit the error is how to traps秀。一个这样的外壳提供了bashthe option for that using setP></

-E

If set, any trap on ERR is inherited by shell functions, command substitutions, and commands executed in a subshell environment. The ERR trap is normally not inherited in such cases.

亚当回答rosenfield' S推荐的使用权在一定set -eis to but has案例pitfalls恩自己的潜能。欧洲经济区greycat' S - 105 -为什么不bashfaq集和(或errexit集或ERR陷阱,或预期的)做什么?P></

根据the手册,和exits集P></

if a simple commandexits with a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test in a if statement, part of an && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command's return value is being inverted via !".

set -edoes not work which means,以下简单的案例(the following detailed explanations can be found on the wiki)P></

  • letusing the arithmetic经营者或$((..))(4.1 bash增量变量值在onwards as to)P></

    1
    2
    3
    4
    5
    #!/usr/bin/env bash
    set -e
    i=0
    let i++                   # or ((i++)) on bash 4.1 or later
    echo"i is $i"
  • 如果offending is not the part of the last命令或命令executed &&||路径。例如,below for the when its陷阱就不会火expected toP></

    1
    2
    3
    4
    #!/usr/bin/env bash
    set -e
    test -d nosuchdir && echo no dir
    echo survived
  • 在incorrectly when used as the statement安if退出队列,ifstatement of the Code of the last is the executed exit命令。在executed the example below the last命令echowhich was the陷阱就不会火,即使test -dfailed theP></

    1
    2
    3
    4
    5
    #!/usr/bin/env bash
    set -e
    f() { if test -d nosuchdir; then echo no dir; fi; }
    f
    echo survived
  • when used with命令取代,除非他们是忽视的,集bash4.4 inherit_errexitis withP></

    1
    2
    3
    4
    #!/usr/bin/env bash
    set -e
    foo=$(expr 1-1; true)
    echo survived
  • 当你使用类的外观,但assignments commands是T,such as exportdeclarelocaltypeset前。在这里fwill not to the function呼叫退出as the error code that has swept localpreviously是集。P></

    1
    2
    3
    set -e
    f() { local var=$(somecommand that fails); }        
    g() { local var; var=$(somecommand that fails); }
  • 当管道是在offending is not,and the part of the last命令的命令。例如,以下命令for the仍然会去通。期权是一pipefailto enable the exit code of the校正模式的过程:第一。P></

    1
    2
    3
    set -e
    somecommand that fails | cat -
    echo survived
  • 推荐使用is not to the理想和实施"订单set -eversion of an自身误差而不是检查。更多信息的在线执行自定义处理的误差在线one of answers to提高误差在bash脚本P></