Do I need to quote command substitutions when assigning their output to a variable?

You do not need to quote the expression on the right side of an assignment.

What is irritating you is that the other answer recommends to quote nevertheless. But this is only about code maintenance.

Consider the following correct example:

DIRNAME=$(dirname "$FILE")
echo "debug: dirname is $DIRNAME"

Now after a while using this script you may think that debug message could be removed. So using an editor you will remove the echo line. Then you'll notice that you don't even need the variable DIRNAME anymore and you simply move the ls command to replace the left site of the assignment. Now you may forget to add the needed quotes and you end up with this broken script:

ls $(dirname "$FILE")

The probability for such mistake is even higher if the first author is a shell expert but the second editor is a newbie.

It's of course debatable whether this recommendation to avoid a portable shell feature is really useful. Personally I do it mostly like he recommends. I also do this for the more "simple" assignments like: var="${foo}" (including superfluous curly braces too).

As one reference, Bash's manual is clear on this:

A variable may be assigned to by a statement of the form


If value is not given, the variable is assigned the null string. All values undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal (detailed below). [...] Word splitting is not performed, with the exception of "$@" as explained below. Filename expansion is not performed.

No word splitting, no filename expansion, therefore no need for quotes.

As for POSIX, section 2.9.1 Simple Commands:

2. The words that are not variable assignments or redirections shall be expanded. If any fields remain following their expansion If any fields remain following their expansion, the first field shall be considered the command name and remaining fields are the arguments for the command.
4. Each variable assignment shall be expanded for tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal prior to assigning the value.

I'm not sure if that's supposed to be interpreted to mean that field splitting happens only for expansions done at step 2? Step 4 does not mention field splitting, though the section on Field splitting also doesn't mention variable assignments as an exception to producing multiple fields.