Windows Subsystem for Linuxガイド 第44回 bash設定 シェルオプション編その3
2025年4月14日(月)11時21分 マイナビニュース
今回は、その他に分類したシェルオプションを解説して、シェルオプション解説の最後としたい。(表01)は、筆者がその他に分類したシェルオプションである。なぜ「その他」なのかというと、用途が特殊であったり、設定項目というよりも、状態報告のために使われるものや、過去のバージョンとの互換性のためのものであることが多い。
なお、スクリプトが実行されるのは、別シェルとなるため、スクリプトに対してシェルオプションを適用したい場合には、スクリプト内で設定する必要がある。あるいは、スクリプト先頭にシバンを置く場合には、大文字0オプション([-+]O [shopt_option])を引数として指定することもできる。
その他のオプションは、大きく6つに分類した。「パターンマッチ」は、bashのパターンマッチングの動作に何らかの変更を加えるもの。「変数」は、ローカル変数の挙動に関しての設定である。「エラー」は、特定の条件をエラーにするかどうか、エラーフォーマットなどの指定を行うもの。「シェル情報」は、動作中のシェルに関する情報を与えるもの。
「終了条件」としたのは、bashプロセスの終了条件やそのときの振る舞いを設定するものだ。最後の「互換性」は、過去のbashバージョンと同じ挙動に戻すためのもの。古いスクリプトなどを動かさねばならないような場合に使うが、自作のものやドキュメントがない限り、そのバージョンのbashで動作していたのかを知るのが困難な場合もある。
動作の確認には、WSL バージョン: 2.4.12.0(カーネル バージョン: 5.15.167.4-1)でUbuntu-24.04 LTSを使った。シェルは、GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)を利用して検証を行った。また、オプションの情報に関しては、
・Bash Reference Manual(英語)
を参考にした。bashのバージョンが異なると動作が異なることがあるため、手元のマシンでの検証時にはバージョンを確認されたい。
パターンマッチ、変数
パターンマッチでわかりにくいオプションは、patsub_replacementである。これは、パラメータ展開のパターンの置換で、一致パターンを表す正規表現「&」の有効、無効を切り替えるもの。標準で有効で、&は一致パターンに置き換えられる(写真01)。
変数に関するシェルオプションは、ローカル変数に関係するもの。「localvar_inherit」と「localvar_unset」の2つがあるが、どちらも説明だけではわかりにくい。
localvar_inheritは、ローカル変数の継承を制御するもの。標準ではオフ(無効)になっている。有効な場合、呼び出し先の関数で同名のローカル変数を定義すると、呼び出し元の関数値を引き継ぐ(写真02)。リスト01に、使ったスクリプトを示す。
■リスト01
f1(){
local mylocalvar='Local Var'
f2
}
f2(){
local mylocalvar
echo $mylocalvar
}
echo "# mylocalvar is 'Local Var'"
shopt -s localvar_inherit
shopt localvar_inherit
echo '# exec f1'
echo "mylocalvar is '$(f1)'"
echo ''
shopt -u localvar_inherit
shopt localvar_inherit
echo '# exec f1'
echo "mylocalvar is '$(f1)'"
localvar_unsetは、ローカル変数をunsetしたときの動作を制御する。こちらも標準は無効(オフ)状態である。有効にすると、呼び出し元で定義したローカル変数を呼び出し先でunsetすると、変数自体は残るが、値がない状態となる。これに対して無効(オフ)では、変数自体が消えてしまう(写真03)。同じく、使ったスクリプトをリスト02に示す。
■リスト02
f1(){
local var1='Var1'
echo -e "\tf1:$(declare -p var1)"
echo ""
f2
echo -en "\tf1:"
echo -e "$(declare -p var1)"
}
f2(){
echo -e "\tf2:unset var1"
unset var1
echo -en "\tf2:"
echo -e "$(declare -p var1)"
echo ""
}
shopt -s localvar_unset
shopt localvar_unset
f1
shopt -u localvar_unset
shopt localvar_unset
f1
エラー、シェル情報、終了条件
エラーカテゴリでは、「failglog」、「gnu_errfmt」を説明しておく。
failglogは、パス名展開のとき、パターンが一致しなかった場合の挙動を変える。標準状態では、無効(オフ)で、パターンが一致しなかったときエラーにならず、パターンがそのまま残る(写真04)。
このオプションを有効にすると、パターンが一致しなかった場合にエラーとなる。思わぬ誤動作を心配するなら有効にしておいてもいいだろう。
gnu_errfmtは、スクリプト実行時のエラーの出力をGNU標準形式とするかどうかである(写真05)。コマンドラインから直接実行したときのエラーメッセージには影響がないので注意されたい。
終了条件カテゴリで、分かりづらいのは、「inherit_errexit」だろう。これは「set -e」(set -o errexit)によるエラー終了の動作を変えるものだ。
「set -e」を設定すると、エラーでスクリプトの実行が中止されるが、エラー発生の位置によっては、中止されないことがある。たとえば、セミコロンで複数のコマンドを区切って実行したとき、途中のコマンドでエラーが発生しても、最後のコマンドが成功すれば、スクリプト実行は中止されない。このためスクリプトの残りの部分を実行してしまう(写真06)。しかし、この「inherit_errexit」を有効にすると、エラーが発生した時点でスクリプトの実行が止まる。
テストに使ったスクリプトをリスト03、リスト04に示す。
■リスト03
set -o errexit
shopt -s inherit_errexit
output=$(xyz; echo ok)
echo "after Error!!"
■リスト04
set -o errexit
shopt -u inherit_errexit
output=$(xyz; echo ok)
echo "after Error!!"
シェルオプションは、新機能やPOSIXや他のシェルで一般的な動作を取り込むために作られたものが少なくない。また、bashのバージョンが上がるとき、これまで無効が標準だったシェルオプションが有効となることもある。
≫ Windows Subsystem for Linuxガイド 連載バックナンバー
https://news.mynavi.jp/tag/winsubsystem/