I am having trouble wrapping my head around how command substitution works when part of the command's parameters come from a variable.
To illustrate, I'll just present a series of commands:
I'll first create a directory A B C
in my tmp directory, in the new directory I'll create a new file abcfile
:
user@desktop /tmp
$ pwd
/tmp
user@desktop /tmp
$ mkdir "A B C"
user@desktop /tmp
$ ls
'A B C'
user@desktop /tmp
$ touch "A B C"/abcfile
user@desktop /tmp
$ ls "A B C"/
abcfile
I'll new assign the value A B C
to a variable $DIR
and attempt to call ls
to list the contents of this directory using various ways of calling the command
user@desktop /tmp
$ DIR="A B C"
With the variable unquoted, the command fails as expected
user@desktop /tmp
$ ls $DIR
ls: cannot access 'A': No such file or directory
ls: cannot access 'B': No such file or directory
ls: cannot access 'C': No such file or directory
With the variable quoted, it works as expected
user@desktop /tmp
$ ls "$DIR"
abcfile
If I want the output of the command as a string
user@desktop /tmp
$ echo $(ls "$DIR")
abcfile
This command works, but why does it work? According to shellcheck this is actually not correct, the variable should be outside of double quotes
user@desktop /tmp
$ echo "$(ls "$DIR")"
abcfile
If the inner variable is not double quoted, the command fails
user@desktop /tmp
$ echo "$(ls $DIR)"
ls: cannot access 'A': No such file or directory
ls: cannot access 'B': No such file or directory
ls: cannot access 'C': No such file or directory
"$(ls "$DIR")"
that isn't quoted isls
. I don't think the duplicate draws that to the fore, but it helps to understand that. – Michael Homer Jun 26 '19 at 06:32