タイトル: set シェルオプションと位置パラメータの操作
SEOタイトル: set コマンドでシェルオプションと位置パラメータを操作 | bash
| この記事の要点 |
|
概要
set はシェル組み込みコマンドで、主な役割は 3 つあります。(1) シェルのオプション (動作モード) を切り替える、(2) 位置パラメータ $1 $2 ... を再設定する、(3) 引数なしで実行するとシェル変数と関数の一覧を表示する。とくにシェルスクリプトでは、エラーハンドリングを厳密にするために set -euo pipefail を冒頭に書くのが定石になっています。
基本構文
set # シェル変数と関数の一覧表示
set -o # 全オプションの状態表示
set -e # コマンドが失敗したら即終了
set +e # 上の解除
set -- arg1 arg2 arg3 # 位置パラメータを置き換え
set -- *.txt # シェルで展開した結果を位置パラメータに
# まとめて指定
set -euo pipefail # スクリプト冒頭の定型句主要オプション
| オプション | 意味 |
|---|---|
-e | コマンドが非ゼロで終了したらスクリプトを即停止 (errexit) |
-u | 未定義変数の参照をエラーにする (nounset) |
-x | 実行する各コマンドを + cmd 形式で標準エラーに出力 (xtrace) |
-n | コマンドを実行せず構文チェックのみ (noexec) |
-o pipefail | パイプの途中で失敗したら全体を失敗扱い |
-o noclobber | > でファイル上書きを禁止 |
-f | パス名展開 (ワイルドカード) を無効化 (noglob) |
-- | これ以降は位置パラメータの値 |
実用例
1) 安全なスクリプトの冒頭
#!/bin/bash
set -euo pipefail
IFS=$"\n\t"
# 以降、エラーが出たら即停止、未定義変数も検出2) 実行トレースで挙動を確認
set -x
for f in *.log; do
gzip "$f"
done
set +x3) パイプの失敗を検出
set -o pipefail
grep ERROR app.log | head -n 5
# grep が失敗しても、pipefail がなければ head の成功で全体が成功扱いになる4) 位置パラメータの置き換え
set -- *.txt
echo "Found $# files"
for f in "$@"; do
echo "- $f"
done5) 構文チェックだけ行う
bash -n script.sh # set -n を引数で指定して構文確認関連コマンドとの比較・組み合わせ
shopt は bash 固有のオプション (例: nullglob, extglob, globstar) を切り替えるコマンドで、set とは独立した拡張です。両者を併用してスクリプトの挙動を厳密化することが多いです。
trap はシグナルやエラーをフックして任意の処理を行うコマンドで、set -e と組み合わせて「失敗時にクリーンアップ」を実装する定番パターンがあります (trap "cleanup" EXIT ERR)。
unset は変数を削除するコマンドで、set とは方向性が逆 (削除専用)。
注意点・落とし穴
set -eは便利だが、パイプ・サブシェル・関数の中で挙動が直感に反することがある (POSIX より bash 拡張部分が複雑)- 条件分岐 (
if cmd; then) では非ゼロ終了が errexit を発火させない、というルールを覚えておく set -u下では${VAR:-default}のような展開を使わないと、未定義参照でエラーになるset -xは機密情報も出力するので、ログ収集環境では注意- 位置パラメータの
set --は、引数解析後に値を保存・置き換える用途で頻出だが、最初の--を忘れると先頭引数がオプションとして解釈されて事故になる