Bash の引用符はコマンド置換でエスケープされません

Bash の引用符はコマンド置換でエスケープされません

これがなぜ機能するのか (名前に空白が含まれるディレクトリの内容を一覧表示する) を誰か説明してもらえますか。

ret="$(ls "my dir")"

むしろ次のように解釈すべきではないでしょうか:

ret="$(ls "
my dir
")"

例えば次のようになります:

ls "my" "dir"

そして

ls "my dir"

答え1

これまでのところ、あなたが尋ねているのは次のような質問であると思われます:

コマンド

    ret="$(ls "私のディレクトリ")"

これは、4 つの二重引用符 ( ) マークを含むコマンドの非常にひどい例です"。次のように、2 番目の引用符が最初の引用符と一致し、4 番目の引用符が 3 番目の引用符と一致すると単純に予想するかもしれません。

    ret="$(ls "my dir")"
        ↑-----↑      ↑-↑

例えば、

    eat "afternoon snack" dinner "midnight snack"

代わりに、次のように「機能します」。

    ret="$(ls "私のディレクトリ")"
        ↑ ↑------↑ ↑
        ↑--------------↑

ネストされた引用符がなぜそのように解析されるのでしょうか?

この段落のバッシュ(1) それは次のように説明できるかもしれない:

コマンド置換

                        ⋮
    …形式を使用する場合、括弧内のすべての文字がコマンドを構成します …。$(command)

$(これは、あなたが観察したことを意味していると思います。つまり、と の間のテキストは、)括弧の外側の構文要素とは関係なく、独自の解析/引用符の組み合わせを持つ別のコマンドであるかのように扱われます。その意味を探していない場合は、解釈が非常に難しいことは認めます。


しかし、あなたの質問は、書かれているとおり意味をなさない。すべては$シェルの特別な意味にかかっている。それを他の通貨記号に変えれば、

    ret="£(ls "my dir")"

2 つの単語として扱われます。

        ret="£(ls "my
(に続く)
                                    dir")"

なぜなら、空白以外の特殊文字が引用符の直前または引用符の直後に現れると、その文字は引用符で囲まれた文字と同じ文字列に含まれるからです。例えば、

    cat Wal"*"mart

は、 というファイルではなく というファイル、 というWal*martファイル、 というファイルを検索します。これは 、およびと同等です。同様に、次の例では 4 つの単語を示しています。Wal*martWal"*"martWal\*mart"Wal*mart"

    1" "2 バックル" 私の "靴は /don\'t/be/a/" "/cadet sqrt"(2)"
    ↑-------↑ ↑--------------↑ ↑--------------------↑ ↑-------↑

質問で示した 3 行の内訳をどこで入手したのかわかりません。

関連情報