« テレビ番組等感想 その 494: 2025 年第 1 四半期の纏め | トップページ

2025年5月10日 (土)

Yash 2 その 298: コマンド置換でのエイリアス置換

POSIX.1-2024 では、コマンド置換の中でエイリアス置換がどのやうに働くのかについての規定が明文化された。ただし、規定内容は緩く、シェルによって異なる動作となることを認めてゐる。

$(...) の形式のコマンド置換の中身は、全体を一気に構文解析してから実行されるのか、それともコマンドごとに一つづつ構文解析と実行を繰り返されるのか。以下のコマンドを実行すると、yash (2.58.1) の POSIX 準拠モードでだけ bar と出力され、他の有名どころのシェルでは foo となる。

echo $(
alias echo='echo bar #'
echo foo
)

つまり、ほとんどのシェルはコマンド置換の中身を全て解析し終へてから実行してゐる。では、コマンド置換の中身はいつ構文解析されるのか。以下のコマンドを実行すると、yash の POSIX 準拠モードと ksh (93u+m/1.0.10) と zsh (5.9) では foo と出力され、他のシェルでは空行となる。

f() { echo $(echo); }
alias echo='echo foo'
f

foo が出力されるのは、函数が定義された後に定義されたエイリアスがコマンド置換の中身の構文解析時に展開されてゐることを意味してをり、すなはち、コマンド置換が展開される時にコマンド置換の中身が解析されることを示してゐる。一方で foo と出力される場合はエイリアスが反映されてゐないといふことであるから、函数が定義された時点でコマンド置換の中身も解析されてゐる。

では、エイリアスはその時点で反映されるのか。以下のスクリプトで確かめられる。

alias echo='echo foo'
f() { printf '%s\n' $(echo); }
unalias echo
f

これを実行したときに foo を出力するシェルは、函数を定義した時点で、つまりコマンド置換が構文解析された時点で、コマンド置換の中身も構文解析され、その際にエイリアス置換が行はれてゐることが判る。そのやうなシェルは POSIX 準拠モードでない yash の他に、bash (5.2.32) や dash (0.5.12)、mksh (59c) がある。

POSIX.1-2024 は、コマンド置換の中身が字句解析と構文解析の対象になることは規定してゐるが、それがいつ行はれるのかは明確にしてゐない。Bash の動きを踏まへ (て POSIX.1-2024 が制定されたことを考へ) ると、コマンド置換が構文解析される時点でコマンド置換の中身も構文解析してしまっても POSIX には反しないと解釈してよからう。すなわち、POSIX 準拠モードでない yash (2.58.1) の動きは POSIX 準拠モードでも認められることになる。

|

« テレビ番組等感想 その 494: 2025 年第 1 四半期の纏め | トップページ

コメント

POSIX モードでない bash だと三つとも POSIX 準拠モードの yash と同じ動作になる。

投稿: | 2025年5月10日 (土) 11時10分

コメントを書く



(ウェブ上には掲載しません)




« テレビ番組等感想 その 494: 2025 年第 1 四半期の纏め | トップページ