2010-05-20 65 views
411

我一直在寫一些shell腳本,我會覺得如果有用的話有停止的執行能力表示shell腳本,如果任何命令失敗。請參閱下面的例子:從的bash shell腳本自動退出的錯誤

#!/bin/bash 

cd some_dir 

./configure --some-flags 

make 

make install 

因此,在這種情況下,如果腳本不能改變到指定目錄,然後它當然不希望做一個的./configure以後,如果它失敗。

現在,我清楚地知道,我可以有一個,如果檢查每個命令(我認爲這是一個沒有希望的解決方案),但有一個全局設置,使腳本退出如果其中一個命令失敗?

+1

答案去亞當的關於集-e(精確地想)的細節。還要感謝a_m0d瞭解陷阱信息(儘管不是100%相關)。 – radman 2010-05-20 05:07:20

回答

654

使用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禁用此行爲。

(*)注:

shell就退出,如果失敗的命令是緊跟在直到關鍵字, 的一部分 命令列表的一部分測試如下如果elif保留字,部分 任何命令執行在& &||列表除了以下最終& &命令 ||,管道中的任何命令,但最後一個是 ,或者命令的返回值是否與 相反!

(從man bash

+4

這是否也是Bourne Shell builtin ? – Tom 2012-05-16 19:03:53

+3

@Tom是:請參閱http://pubs.opengroup.org/onlinepubs/009695399/utilities/set.html#tag_04_127_03 – 2013-08-03 20:50:52

+5

'設置+ e'將再次恢復設置,因此您只能自動退出某些塊錯誤。 – olivervbk 2015-04-18 14:36:20

16

一個成語是:

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

我認識到,可以長期做下去,但對於更大的腳本,你可以分解成邏輯功能。

+7

,你可以在'&&'之後添加一個換行符以提高可讀性 – 2010-05-20 11:09:48

15

我認爲你正在尋找的是trap命令:

trap command signal [signal ...] 

欲瞭解更多信息,請參閱this page

另一種選擇是在腳本的頂部使用set -e命令 - 如果任何程序/命令返回非真值,它將使腳本退出。

55

儘快的命令之一失敗退出腳本,一開始補充一點:

set -e 

這使腳本立即退出時,一些命令是不是有些測試的一部分(如在一個if [ ... ]條件或&&構建體)具有非零的退出代碼退出。

+0

更多信息請看:http://www.davidpashley.com/articles/writing-robust-shell-scripts.html#id2382181 – dhornbein 2013-06-13 03:39:20

38

這裏是如何做到這一點:

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

trap'abort'0 < - 爲什麼你在做「0」而不是「1」的陷阱? – MAGx2 2014-09-03 09:50:04

+1

0退出時出現''EXIT'',IOW陷阱 – azat 2015-05-22 21:10:37

+0

如果在EXIT('0')陷阱中不使用「退出」,shell將保留原始退出值並退出! – anthony 2017-01-19 00:25:17

17

到接受的答案,適合在第一行的選擇:

#!/bin/bash -e 

cd some_dir 

./configure --some-flags 

make 

make install 
+4

我以前見過這個(在'!'行放置'-e'),但對於我來說,它在Mac OS X上不能像bash v3.2.57那樣工作。簡單的測試腳本調用/ usr/bin/false其次是回聲請勿在預期時保釋。使用上面接受的「set -e」可以正常工作。 – pauldoo 2015-09-02 19:45:25

17

在case腳本在內部調用下標,pipefail選項可能會有用。

set -e 
set -o pipefail 

-e(errexit):在第一個錯誤中止腳本,當與非零狀態的命令退出(除了在直到或while循環,if-測試,列表構建體)

-o pipefail :使管道返回管道中返回非零返回值的最後一個命令的退出狀態。

Chapter 33. Options

+1

這是「set -o errexit」或「set -e」。 – user1457432 2017-05-28 23:29:19