バックスラッシュエスケープを使用して引用符付き文字列のコマンドを置き換える

バックスラッシュエスケープを使用して引用符付き文字列のコマンドを置き換える

次のようにバックスラッシュエスケープで二重引用符コマンドの置き換えを使用することを検討してください。

echo "$(echo '\\')"

それは印刷されますが、\\私はバックスラッシュだけを印刷すると予想しました。私の考えは(間違った)文字列全体を渡し、すべてのバックスラッシュエスケープを置き換えます。それからコマンド置換を実行します。もちろん、順序は逆です。

しかし、もし私たちがそうするなら

echo "$(echo '\')$"

として印刷されます\$。コマンド置換を行う場合最初その後、その文字列はバックスラッシュエスケープに対して評価され、最終的\には$単一にまとめることができます。$しかしそれは真実ではない。

バックスラッシュエスケープは物事の順序でどこに適していますか?

(この質問の背景は、sedコマンドに挿入するために文字列の正規表現文字を正しくエスケープする方法を研究していることです。)

答え1

echo $(echo '\\')私はそれが(つまり、外部引用符のないバリエーション)の出力として最もよく理解されていると思います、その結果は\\リテラル文字列$(...)エンティティを置き換えるときのバックスラッシュの拡張コマンドの解釈です。 (これはエスケープ文字を文字列に格納するのと似ており、リテラル文字列として再解釈されません。)

答え2

区切りコマンドの置き換えでは、角かっこ内の$(…)内容は最上位コマンドと同じ方法で解析されます(バランスのとれていない閉じ角かっこに関連する特殊な場合を除く)。括弧内には、バックスラッシュ拡張が追加されていない一般的なシェルの断片があります。

このコマンドは、echo '\\'2つのバックスラッシュと1つの改行(echoコマンドがバックスラッシュ拡張を実行しないと仮定)の3文字を印刷します。したがって、コマンド置換の結果$(echo '\\')は2文字の文字列です\\(コマンド置換が常にそうであるように、最後の改行文字は削除されます)。二重引用符でコマンド置換を使用したため、追加の拡張は行われません。結果の単語の部分はです\\

echo "$(echo '\')$"コマンド置換はバックスラッシュを出力します。引数への貢献echoは文字列です\。次の文字は$パラメータ名の先頭文字として使用できないため、パラメータ名自体に展開されます。したがって、echoの引数は2文字の文字列です\$。二重引用符で囲まれた文字列は拡張されなくなり、バックスラッシュを特殊文字として解釈することはできません(コマンドの特定の機能を除くecho)。

可読性の異なる完全な拡張ルールは、シェルマニュアルおよびその他のドキュメントにあります。これPOSIX仕様目安としては悪くありません(微妙な賞賛)。

ポリスチレン「sed」置換に挿入された文字列がすべてのメタ文字をエスケープするかどうかを確認する方法

答え3

引用ともっと関連があります。

$ echo '\'
\
$ echo '\\'
\\
$ echo "\\"
\

一重引用符を使用すると、引用符の間にある内容はすべてエコーされます。二重引用符を使用すると、シェルは内部を見て処理します。

関連情報