Bash quotes unescaped on command substitution

The best guess so far seems to be that you are asking:

The command

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

is a pretty terrible example of a command that contains four double-quote (") marks.  One might naïvely expect that the second quote would match the first one, and the fourth would match the third, like this:

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

as, for example, happens with

    eat "afternoon snack" dinner "midnight snack"

Instead, it “works”, as follows:

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

Why are the nested quotes parsed that way?

This paragraph of bash(1) may explain it:

Command Substitution

                        ⋮
    …  When using the $(command) form, all characters between the parentheses make up the command ….

I guess this means what you have observed, namely, the text between the $( and the ) is treated as if it were a separate command, with its own parsing/pairing of quotes, independent of syntactic elements outside the parentheses.  I concede that, if you aren’t looking for that meaning, it’s very hard to interpret.


But your question, as written, doesn’t make sense.  The whole thing hinges on the very special meaning(s) of $ to the shell.  If we changed that to some other currency symbol,

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

then it would be treated as two words:

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

because, if a non-blank, non-special character appears immediately before an opening quote or immediately after a closing quote, it is included in the same string as the characters enclosed in the quotes.  For example,

    cat Wal"*"mart

looks for a file called Wal*mart, not a file called Wal, one called *, and one called martWal"*"mart is equivalent to Wal\*mart and "Wal*mart".  Similarly, the following example shows four words:

    one" "two  buckle" my "shoe  /don\'t/be/a/" "/cadet  sqrt"(2)"
    ↑-------↑  ↑--------------↑  ↑--------------------↑  ↑-------↑

I don’t know where you got the three-line breakdown that you showed in your question.