test@debian:~$ echo `echo \`echo "uh!"\``
uh!
バッシュはどのようにそれをしますか?最初に、エスケープされていないバッククォートで式を実行し、それが返されるようです(二重引用符 ""は削除されますよね?):
`echo uh!`
したがって、次と同等の入力があります。
test@debian:~$ echo `echo uh!`
(補足:本当に、なぜそれが機能するのですか?理由:
test@debian:~$ echo `echo uh!`
-bash: !`: event not found
)
次に、Bashはバッククォートで式を再度実行します。
test@debian:~$ echo uh!
最終的に出力が得られます。
uh!
そうですか?そして、どのようにしてfourecho
- backtick-expressionを互いにカプセル化できるでしょうか?
bash
のバージョンによって異なります:
bash-4.2$ echo `echo \`echo "uh!"\``
bash: !"\``: event not found
bash-4.3$ echo `echo \`echo "uh!"\``
uh!
bash-4.3
では、!"
は履歴イベント指定子としての資格がなくなったため、履歴拡張は適用されません。
それ以外は、通常のバッククォートのネスト構文です。バックティックの内部では、バックスラッシュ文字がオーバーロードされて(さらに)、ネストされた展開が再度実行されます。
必要な数のレベルをネストできます。
echo `echo \`echo \\\`echo \\\\\\\`echo whatever\\\\\\\`\\\`\``
これは面倒な同等物です:
echo $(echo $(echo $(echo $(echo whatever))))
ただし、どちらのバージョンでも、コマンド置換はWord分割の対象となることに注意してください。だから、あなたはそれを防ぐためにそれらを引用したいと思うでしょう。
bash
、dash
、pdksh
、yash
、zsh
を使用すると、比較的簡単です。
echo "`echo "\`echo "\\\`echo "\\\\\\\`echo whatever\\\\\\\`"\\\`"\`"`"
ボーンシェルまたはコーンシェルでは、"
もエスケープする必要があるため、次のようになります。
echo "`echo \"\`echo \\\"\\\`echo \\\\\\\"\\\\\\\`echo whatever\\\\\\\`\\\\\\\"\\\`\\\"\`\"`"
と比べて:
echo "$(echo "$(echo "$(echo "$(echo whatever)")")")"
これは面白い。
これはええと拡張します:
_echo `echo \`echo uh\``
_
でもない
_echo "`echo \`echo uh\``"
_
内部膨張を抑制します。
bash
シェルとPOSIXシェル(ダッシュ)の両方で、バックティックのネストに適した代替手段として$()
があります。
興味深いことに、内部プロセス置換は、引用符で囲まれているかどうか、または内部置換がバッククォートまたは$()
を使用しているかどうかに関係なく、$()
で展開されません。
_$ echo $(echo \$\(echo uh\))
$(echo uh)
$ echo $(echo \`echo uh\`)
`echo uh`
_
バックティックを使用した暗黙の拡張は、あまり安全に見えません。特にネストしたい場合は、$()
に固執します。