Bash
Shebang
レビュー
シェルスクリプト
レビューアメモ

レビューアメモ: シェルに渡すオプションはshebangではなくsetコマンドで指定しよう

3行まとめ

  • シェルスクリプトを書く時は、1行目にshebang、2行目にsetコマンドを指定すると良い。
  • setコマンドでオプションを指定すると、shebang経由で起動した場合も、シェルにファイル名を指定して起動した場合も有効になる。
  • shebangで指定したオプションは、シェルにファイル名を指定して起動した場合に有効にならない。

参考: shebangについて

シェルスクリプトや各種スクリプト言語のコードの1行目に書いてある以下の様な行を「shebang」(シェバン、シバンと呼ばれることが多い)と言います。

#!/bin/bash

shebangの詳細については『シバン (Unix) - Wikipedia』などをどうぞ。

本題: shebangとsetの挙動の違い

シェル(shbashなど)のオプションを指定する方法として、shebangで指定する方法、setコマンドで指定する方法があります。

shebangで指定する方法:

#!/bin/bash -u

setコマンドで指定する方法:

#!/bin/bash
set -u

なお、本記事の説明では、シェルとしてbash、オプションとして-uを使用します。-uオプションは未定義の変数の参照をエラーとするオプションです。

shebangで指定する方法(おすすめしない方法)

まずは、shebangでオプションを指定した場合の挙動について確認してみます。実験用のファイルはshebang.shで、ファイルのパーミッション、内容は以下の通りです。

$ ls -l shebang.sh
-rwxrwxr-x 1 yuya yuya 42  4月  9 14:10 shebang.sh

$ cat shebang.sh
#!/bin/bash -u
echo ${UNDEFINED_VARIABLE}

shebangを経由して起動した場合、-uオプションが有効となり、未定義変数の参照がエラーとなっています。終了コードも「失敗」を意味する1(非ゼロ)となっています。

$ ./shebang.sh; echo $?
./shebang.sh: line 2: UNDEFINED_VARIABLE: unbound variable
1

一方、シェルの引数としてファイル名を指定して起動した場合、-uオプションが有効とならず、未定義変数の参照がエラーになりません。終了コードも「成功」を意味する0(ゼロ)となっています。

setコマンドを使う方法(おすすめする方法)

次に、setコマンドを使ってオプションを指定した場合の挙動について確認してみます。実験用のファイルはset.shで、ファイルのパーミッション、内容は以下の通りです。

$ ls -l set.sh
-rwxrwxr-x 1 yuya yuya 46  4月  9 14:11 set.sh

$ cat set.sh
#!/bin/bash
set -u
echo ${UNDEFINED_VARIABLE}

shebangを経由して起動した場合、shebang.shと同様に、-uオプションが有効となり、未定義変数の参照がエラーとなっています。終了コードも「失敗」を意味する1(非ゼロ)となっています。

$ ./set.sh; echo $?
./set.sh: line 3: UNDEFINED_VARIABLE: unbound variable
1

また、シェルの引数としてファイル名を指定して起動した場合も、上記と同様、-uオプションが有効となり、未定義変数の参照がエラーとなっています。

yuya@ywr-desktop$ /bin/bash set.sh; echo $?
set.sh: line 3: UNDEFINED_VARIABLE: unbound variable
1

このように、setコマンドを用いると、どちらの方法で起動された場合でも、意図したオプションを渡すことができます。

「レビューアメモ」について

コードレビューのレビューアとして何度かコメントした内容について、情報共有のために記事化したものです。