10.2. Bash (Bourne-Again Shell)
Red Hat Enterprise Linux 6 には Bash のバージョン 4.1 がデフォルトシェルとして収納されています。本セクションではバージョン 4.1 によりもたらされる旧バージョンとの互換性に関する問題点について説明しています。
- Bash-4.0 およびそれ以降のバージョンは、 プロセス置換の構成をブレース展開を使って変更せずに渡すことができるようになるため、 内容の展開はすべて別々に指定し、 各プロセス置換を別々に入力しなければならなくなります。
- Bash-4.0 およびそれ以降のバージョンでは Posix が指定するのと同様に、 SIGCHLD が wait の組込みに割り込みを許可するため、 全ての子を待機するよう「wait」を使用する場合、 子を終了したら SIGCHLD トラップは常に呼び出されることがなくなります。
- Bash-4.0 およびそれ以降のバージョンは、 クローズ用の区切り文字 $() コマンド置換を検索する場合に Posix のルールに従うようになり、 旧バージョンのような動作はしなくなりますが、 より多くの構文および解析のエラーを先に捕らえてからコマンド置換を評価するためのサブシェルを生成します。
- プログラム可能な完了コードはコマンドラインを単語に分解する際にシェルのメタキャラクタのセットではなく読み込み行と同じ区切り文字のセットを使用します。これにより、プログラム可能な完了と読み込み行の一貫性が増します。
- read のビルトインが時間切れになると、 入力の read を指定変数に割り当てようとするため、 十分な入力がない場合には変数が空の文字列にセットされる原因にもなります。 旧バージョンは文字の read を破棄していました。
- Bash-4.0 およびそれ以降のバージョンでは、 パイプラインのコマンドのひとつがコマンド一覧を実行している間に SIGINT によって終了させられた場合、 シェルは割り込みを受けたかのような動作をします。
- Bash-4.0 およびそれ以降のバージョンでは、
set -e
オプションの処理法が変更されるため、 パイプラインが失敗すると (失敗したパイプライン内の最後のコマンドが単純なコマンドでない場合も) シェルは終了します。 これは Posix が指定するものとは異なります。 この部分の基準を更新する作業が進展中です。 Bash-4.0 の動作はリリースの時点での合意を得ようとしている動作です。 - Bash-4.0 およびそれ以降のバージョンでは、
"."
がシステムの PATH に存在しない場合でも、. (source)
ビルトインがファイル名の引数を現在のディレクトリで検索してしまう原因となっていた Posix モードのバグが修正されています。 Posix では、このような場合シェルによる PWD 変数内の検索は行われるべきではないと述べられています。 - Bash-4.1 は、
[[
コマンドに演算子を使用して文字列を比較する場合は現在のロケールを使用します。compatNN
shopt オプションの 1 つをセットすることで以前の動作に戻すことができます。
10.2.1. 正規表現
既に記載されている点に加えて、正規表現に対するパターン引数に引用符を付けて条件演算子 =~ に一致させると、 正規表現の一致が動作しなくなる場合があります。 これは全てのアーキテクチャで起こります。 3.2 以前のバージョンとなる bash では、 [[ コマンドの =~ 演算子に対する正規表現の引数に引用符を付けることによる効果は規定されていませんでした。 実用的な効果としては、 パターン引数に二重引用符を付けると、 バックスラッシュ「/」で特殊パターン文字に引用符を付けなければなりませんでした。 これにより、 二重引用符が付けられた単語展開で行われるバックスラッシュの処理を妨害し、 == シェルパターン一致演算子が引用符が付けられた文字を処理する方法と矛盾していました。
bash バージョン 3.2 では、=~ 演算子に対して一重の引用符が付けられた文字列引数および二重の引用符が付けられた文字列引数内の文字には内部的に引用符が付けられるようシェルが変更されました。 これにより、 (「`.'」、 「`['」、 「`\'」、 「`(', `)」、 「`*'」、 「`+'」、 「`?'」、 「`{'」、 「`|'」、 「`^'」、 「`$'」) を処理する正規表現に重要となる文字の特殊な意味を抑制し、 そのまま強制的に一致が行われるようにします。 == パターン一致演算子がそのパターン引数内の引用符が付けられた部分を処理する方法との矛盾がなくなります。
引用符付き文字列引数の処理が変更されてから問題がいくつか出現してきています。 主要な問題として、 パターン引数内の空白、 bash 3.1 と bash 3.2 間で引用符付き文字列の処理が異なるなどの問題があげられます。 いずれの問題もシェル変数を使ってパターンを維持することで解決できます。 [[ コマンドの全オペランドでシェル変数を展開する場合には単語の分割は行われないため、 変数を割り当てる時に好きなようにパターンに引用符を付けてから、 空白を含む可能性がある単独の文字列にその値を展開することができるようになります。 最初の問題は、 バックスラッシュか他の引用メカニズムを使用してパターン内で空白をエスケープすることで解決します。
Bash 4.0 は shopt ビルトインに対するいくつかのオプションで制御される 互換性レベル の概念を取り入れています。 compat31 オプションを有効にすると、 bash は =~ 演算子の右側の引用に関して 3.1 の動作を取り戻します。