さまざまなシェルを使用して複数のスクリプトをテストしましたが、結果はさまざまでした。
# test 1
foo(){ echo $(al);}
alias al='echo 123'
foo
# test 2
alias al='echo 123'
foo(){ echo $(al);}
alias al='echo abc'
foo
# test 3
alias foo='echo $('
echo $(foo echo '123'))
# test 4
alias foo='echo $('
echo "$(foo echo '123'))"
# test 5
alias bar='echo 123)'
echo $(bar
bash 5.1.16 (--posix を使用) | 昆山 2020.0.0 | zsh 5.9 | ダッシュ 0.5.12 | ヤッシュ 2.53 | |
---|---|---|---|---|---|
テスト1 | 123 | 123 | 123 | 卵:見つかりません | そのようなコマンドはありませんal |
テスト2 | アルファベット | アルファベット | アルファベット | 123 | 123 |
テスト3 | 予期しないマーク) |
) 事故 |
123 | 123 | 123 |
テスト4 | 123 | 123 | 123 | 123 | 123 |
テスト5 | 予期しないファイルの終わり | ( 耐え難い |
コマンドが見つかりません:barecho | 123 | 123 |
したがって、基本的にbashとkshは遅延エイリアス置換を実行し、dashとyashは劣性エイリアス置換を実行します。 zshの動作は説明が少し難しいです。特にコマンドを見つけようとすると、5の場合はさらにそうですbarecho
。
テスト4は、すべてのシェルが一致する唯一のケースです。これは混乱しています。なぜならPOSIX規格 2.2.3二重引用符説明する:
"$(" と一致する ")" の間に含まれる引用符付き文字列の入力文字は、二重引用符の影響を受けてはいけませんが、代わりに単語が展開されたときに出力が "$(...)" を置き換えるコマンド定義する必要があります。 。一致する「)」を見つけるには、トークン認識のトークン化規則(別名置換の別名置換を除く)を繰り返し適用する必要があります。
標準では、二重引用符内のコマンド置換で一致する括弧を見つけようとすると、シェルはエイリアス置換を使用しないでください。ただし、すべてのシェルは二重引用符内にエイリアス置換を使用し、一部のシェルは二重引用符なしでは使用しません。
問題は、特定の状況で特定のシェルが間違っているのか、それとも別のものかです。つまり、この状況で正しい行動が何であるかを示すいくつかの規則がありますか?