bashスクリプトでのset -eの意味は?

パッケージがDebianアーカイブ(.deb)ファイルから解凍される前に、スクリプトが実行するこのpreinstファイルの内容を調べています。

このスクリプトには以下のようなコードがあります。

#!/bin/bash
set -e
# Automatically added by dh_installinit
if [ "$1" = install ]; then
   if [ -d /usr/share/MyApplicationName ]; then
     echo "MyApplicationName is just installed"
     return 1
   fi
   rm -Rf $HOME/.config/nautilus-actions/nautilus-actions.conf
   rm -Rf $HOME/.local/share/file-manager/actions/*
fi
# End automatically added section

最初の問い合わせは、この行についてです。

set -e

このスクリプトの残りの部分は非常にシンプルだと思います。Debian/Ubuntuのパッケージマネージャがインストール操作を実行しているかどうかをチェックします。実行中であれば、私のアプリケーションがシステムにインストールされたばかりかどうかをチェックします。インストールされていれば、スクリプトは "MyApplicationName is just installed" というメッセージを表示して終了します(return 1 というのは、「エラー」で終わるということですね)。

ユーザーがDebian/Ubuntuのパッケージシステムに私のパッケージをインストールするように要求している場合、スクリプトは2つのディレクトリも削除します。

これは正しいのでしょうか、それとも私が何か見逃しているのでしょうか?

ソリューション

from help set :

  -e  Exit immediately if a command exits with a non-zero status.

しかし、これは一部の人(bash FAQ や irc freenode #bash FAQ の作者)には悪い習慣とされています。使うことが推奨されています。

trap 'do_something' ERR

を使って、エラー発生時に do_something 関数を実行することを推奨します。

http://mywiki.wooledge.org/BashFAQ/105 を参照してください。

解説 (13)

set -eは、コマンドやパイプラインにエラーがあった場合、スクリプトの実行を停止します。これは、スクリプトのエラーを無視するというシェルのデフォルトの動作とは逆になります。ターミナルでhelp set` と入力すると、この組み込みコマンドのドキュメントが表示されます。

解説 (2)

bash - The Set Builtin]1マニュアルによると、-e/errexitが設定されていると、単一の[単純なコマンド][3]、[リスト][4]、複合コマンドからなるパイプラインがゼロ以外のステータスを返した場合、シェルは直ちに終了します。

デフォルトでは、パイプラインの終了ステータスは、pipefailオプションが有効でない限り、パイプライン内の最後のコマンドの終了ステータスになります(デフォルトでは無効です)。

その場合、パイプラインの最後の(右端の)コマンドの終了ステータスがゼロ以外のステータスで返され、すべてのコマンドが正常に終了した場合はゼロになります。

終了時に何かを実行させたい場合は、例えばtrapを定義してみてください。

trap onexit EXIT

ここで、onexit は終了時に何かを行う関数で、以下のようにシンプルな スタックトレース を表示します。

onexit(){ while caller $((n++)); do :; done; }

同様のオプション -E/errtrace があり、これは代わりに ERR をトラップします。

trap onerr ERR

ゼロの状態の例。

$ true; echo $?
0

ゼロでない状態の例

$ false; echo $?
1

負のステータスの例:{{22830261}}。

$ ! false; echo $?
0
$ false || true; echo $?
0

pipefail` を無効にしてテストします。

$ bash -c 'set +o pipefail -e; true | true | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; false | false | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; true | true | false; echo success'; echo $?
1

pipefail`を有効にしてテストします。

$ bash -c 'set -o pipefail -e; true | false | true; echo success'; echo $?
1

[3]: https://www.gnu.org/software/bash/manual/html_node/Simple-Commands.html#Simple-Commands [4]: https://www.gnu.org/software/bash/manual/html_node/Lists.html#Lists

解説 (0)