I know the whole language is confusing, but I am having trouble understanding assignments with command substitutions:
x=Example sentence #1 fails due to space
x='Example sentence' #2 ok
echo $x #3 ok
[ -n $(echo $x) ] && echo foo #4 fails due to space
[ -n "$(echo $x)" ] && echo foo #5 ok
y=$x #6 ok
y=$(echo $x) #7 ok, not like 1?
[ -n $y ] #8 fails due to space
With practice, I have learned that command substitutions in tests should always be surrounded by quotes (e.g. [ -n "$(cmd)" ]
), and that quotes can be used inside the substitution without interfering with outside quotes. Quoting a substitution seems to capture stdout
, but not stderr
(unless redirected).
Q1. But what happens when the substitution is not quoted (cases 4 and 7)?
Specifically, I am confused with the apparent difference in behaviour between assignments x=$(cmd)
, which seem to work fine with spaces, versus tests [ -n $(cmd) ]
, which seem to always be truthy.
Q2. Is it bad practice to assign command substitutions without quotes x=$(cmd)
? Should I always quote them x="$(cmd)"
?
[[ ]]
is another special case, but single brackets[ ]
require quotes. ---- Q1: assignments are just special. Q2: it's fine not to quote. – Jonathan H Jul 18 '18 at 13:24