Bashスクリプトが終了する前にコマンドを実行する方法は?


119

Bashスクリプトにがありset -e、スクリプト内のコマンドがエラーを返す場合、スクリプトが終了する前にクリーンアップを行うにはどうすればよいですか?

例えば:

#!/bin/bash
set -e
mkdir /tmp/foo
# ... do stuff ...
rm -r /tmp/foo

/tmp/fooのコマンドの1つが... do stuff ...失敗した場合でも、それを確実に削除するにはどうすればよいですか?

回答:


193

次にトラップの使用例を示します。

#!/bin/bash -e

function cleanup {
  echo "Removing /tmp/foo"
  rm  -r /tmp/foo
}

trap cleanup EXIT
mkdir /tmp/foo
asdffdsa #Fails

出力:

dbrown@luxury:~ $ sh traptest
t: line 9: asdffdsa: command not found
Removing /tmp/foo
dbrown@luxury:~ $

asdffdsa行が失敗しても、クリーンアップが実行されたことに注意してください。


11

bash(ビルトインに関する)マンページから:

trap [-lp] [[arg] sigspec ...]
シェルがシグナルsigspecを受信すると、コマンドargが読み取られて実行されます。

したがって、Anon。の回答に示されているようtrapに、スクリプトの早い段階で呼び出して、ERRで必要なハンドラーを設定します。


実行help trapすると、組み込みのヘルプが表示されます。
Flimm 2014

8

の参照からset

-e

失敗したコマンドがuntilまたはwhileループの一部、ifステートメントの一部、&&または||の一部でない限り、単純なコマンド(セクション3.2.1単純なコマンドを参照)がゼロ以外のステータスで終了した場合、すぐに終了します。リスト、または!を使用してコマンドの戻りステータスが反転している場合。設定されている場合、ERRのトラップは、シェルが終了する前に実行されます。

(エンファシス鉱山)。


「-e」を使用する場合は「-E」を追加する価値があるかもしれません。vaneyckt.io/ posts / safer_bash_scripts_with_set_euxo_pipefail
Max Barraclough

3

shdevguydavidの回答のバージョン。

#!/bin/sh
set -e
cleanup() {
  echo "Removing /tmp/foo"
  rm  -r /tmp/foo
}
trap cleanup EXIT
mkdir /tmp/foo
asdffdsa #Fails

ref:shellscript.sh


POSIX私をにっこりさせる。:)あなたもリンクした素晴らしい教育サイト。
Cometsong
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.