Non-modern Shell Programing (4)

2.6.3 コマンド置換

コマンド置換は、コマンドの出力がコマンド名自体の代わりとして置換されることを許す。コマンド置換はコマンドが下記によって囲まれている時に起こるものとする。

$(コマンド)

または(バッククォートされたバージョン):

`コマンド`

シェルはサブシェル環境内でコマンドを実行し、コマンドの標準出力によってコマンド置換(コマンドのテキストと、それを囲んでいる"$()"やバッククォート)を置き換えることでコマンド置換を展開する。展開の際に、置換の終端の1個以上の<改行>文字群からなる列を取り除く。出力終端より前の埋め込まれた<改行>文字群は取り除かれない。しかし、IFSの値と、実施されているクォートによっては、フィールドデリミタとして扱われ、フィールド分割の間に除去されるかもしれない。出力がヌルバイトを含んでいたら、振る舞いは不定である。

バッククォート方式のコマンド置換内では、'$'や'`'や<バックスラッシュ>が後に続かない限り、<バックスラッシュ>は字義通りの意味を持つものとする。マッチするバッククォートの検索は、クォートされていない最初の非エスケープバッククォートによって満たされる。シェルコメントやヒアドキュメントや$(コマンド)方式の埋め込まれたコマンド置換やクォートされた文字列のなかで、非エスケープバッククォートに遭遇した場合、未定義の結果が起こる。"`...`"列内で、開始しているが終了していないシングルクォートまたはダブルクォート文字列は未定義の結果を引き起こす。

$(コマンド)方式内では、開き括弧からそれにマッチする閉じ括弧までのすべての文字群がコマンドを構成する。リダイレクションからなるスクリプト不定の結果を引き起こす)を除いて、あらゆる妥当なシェルスクリプトをコマンドとして用いることができる。

コマンド置換の結果は、さらなるチルダ展開やパラメータ展開やコマンド置換や算術展開の処理をされないものとする。コマンド置換がダブルクォート内で起きたら、フィールド分割とパス名展開はコマンド置換の結果に対して実行されないものとする。

コマンド置換は入れ子になりうる。バッククォートされたバージョン内で入れ子を指示するために、アプリケーションは内側のバッククォートに<バックスラッシュ>文字を先行させるものとする。例えば、

\`コマンド\`

下記のようにコマンド置換が1個のサブシェルからなるならば、

$( (コマンド) )

準拠アプリケーションは"$("と'('を(つまり、空白で分割されている)2個のトークンに分割するものとする。これは算術展開との不明確さをさけるために必要である。

2.6.3 Command Substitution