tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

シェルスクリプトやbashの処理を中断する3パターンの`-e` - とアンチパターン

はじめに

シェルスクリプトを書いていて
予想外の失敗時に処理が先に進まないでほしい
場合に処理を中断してほしいことがありますよね。

そんなときのメモ

アジェンダ

どうやるか

-eオプションをつけます。

-eをつけることで、exit 0(正常ステータス)
以外が返る場合に処理を中止するようになります。

どう使うか

-eオプションでの実行は何パターンかあります

  1. bashコマンドのオプションにつけてシェルスクリプトを実行する
  2. シェルスクリプトshebangにつける
  3. シェルスクリプト内で"set -e"を呼ぶ

具体例

サンプル

以下のようなシェルスクリプトサンプルで説明します。

  • stop.sh
$ cat stop.sh
#!/bin/bash

echo "hoge" # あってる
ehco "fuga" # echoをスペルミス
echo "piyo" # あってる
  • そのまま実行した場合
$ ./stop.sh
hoge
./stop.sh: line 4: ehco: command not found
piyo

line 4: ehco: command not found とは表示されますが、
piyoまで出力されています。

1. bashコマンドのオプションにつけてシェルスクリプトを実行する

シェルスクリプトの実行時にbashコマンド + -eで実行します

$ bash -e stop.sh
hoge
stop.sh: line 4: ehco: command not found

piyoが出力されずに処理が中断されました。

2. シェルスクリプトshebangにつける

シェルスクリプトの冒頭に記載する#!/bin/bash-eをつけます

  • stop.shを以下のように変更します
$ cat stop.sh
#!/bin/bash -e

echo "hoge" # あってる
ehco "fuga" # echoをスペルミス
echo "piyo" # あってる
  • 実行
$ ./stop.sh
hoge
./stop.sh: line 4: ehco: command not found

piyoが出力されずに処理が中断されました。

3. シェルスクリプト内で"set -e"を呼ぶ

シェルスクリプトの冒頭でset -eします。

  • stop.shを以下のように変更します
$ cat stop.sh
#!/bin/bash

set -e

echo "hoge" # あってる
ehco "fuga" # echoをスペルミス
echo "piyo" # あってる
  • 実行
$ ./stop.sh
hoge
./stop.sh: line 4: ehco: command not found

アンチパターン

しかし、注意することがあります。

2. シェルスクリプトのshebangにつけるbashコマンドで呼び出すとうまくいきません。

  • stop.sh
$ cat stop.sh
#!/bin/bash -e

echo "hoge" # あってる
ehco "fuga" # echoをスペルミス
echo "piyo" # あってる
  • 実行
# そのまま実行
$ ./stop.sh
hoge
./stop.sh: line 4: ehco: command not found

# bashコマンドで呼び出し
# piyoまで出力されてしまう
$ bash ./stop.sh
hoge
./stop.sh: line 4: ehco: command not found
piyo

これだと意図せず中断したいから大丈夫だろうと思いつつ
意図せず続いてしまうのでだいぶむしろ怖いです。

3. シェルスクリプト内で"set -e"を呼ぶのほうは大丈夫です

$ cat stop.sh
#!/bin/bash

set -e

echo "hoge" # あってる
ehco "fuga" # echoをスペルミス
echo "piyo" # あってる

$ ./stop.sh
./stop.sh
hoge
./stop.sh: line 6: ehco: command not found

$ bash stop.sh
hoge
stop.sh: line 6: ehco: command not found

合わせて

おわり

set -eは若干の賛否両論はありますが、 意図せず処理を続けることがないようにしたい場合は
シェルスクリプト内にset -eするのが安心です\(^o^)/