バックティックコマンドのカプセル化

バックティックコマンドのカプセル化
test@debian:~$ echo `echo \`echo "uh!"\``
uh!

Bashはこれをどのように実行しますか?まず、エスケープされていない逆引用符で式を実行して次を返すようです(二重引用符 ""は削除されます。そうですか?)。

`echo uh!`

したがって、次のような入力があります。

test@debian:~$ echo `echo uh!`

(注:実際にはなぜ動作しますか?

test@debian:~$ echo `echo uh!`
-bash: !`: event not found

)

その後、Bashは逆引用符内の式を再実行して次のようになります。

test@debian:~$ echo uh!

最後に出力を提供します。

uh!

そうなんですか?そしてカプセル化する方法4つ echo- バックティック式を互いに変換するか、逆に変換しますか?

答え1

バージョンによって異なります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))))

ただし、両方のバージョンでは、コマンドの置き換えは単語の分離の影響を受けます。したがって、これが発生しないようにするには、これを参照する必要があります。

bash、、、、、を使用するのはdash比較的簡単ですpdkshyashzsh

echo "`echo "\`echo "\\\`echo "\\\\\\\`echo whatever\\\\\\\`"\\\`"\`"`"

Bourne または Korn シェルでは、"次のように while をエスケープする必要があります。

echo "`echo \"\`echo \\\"\\\`echo \\\\\\\"\\\\\\\`echo whatever\\\\\\\`\\\\\\\"\\\`\\\"\`\"`"

比較:

echo "$(echo "$(echo "$(echo "$(echo whatever)")")")" 

答え2

興味深いです。

これは次のように拡張されます。

echo `echo \`echo uh\``

でも

echo "`echo \`echo uh\``"

内部拡張を抑制します。

bashPOSIX シェルと POSIX シェル (ダッシュ) では、ネストに優しい$()代替としてバックティックを使用できます。

$() 興味深いことに、プロセス内の置き換えは、引用されているのか、内部の置換がバックティックであるのか、または次のものを使用しているのかに関係なく拡張されません$()

$ echo $(echo \$\(echo uh\))
  $(echo uh)
$ echo $(echo \`echo uh\`)
  `echo uh`

バックティックを使用した暗黙の拡張は安全ではないようです。$()特に巣を建てたい場合はさらにそうです。

関連情報