In the command-line Bash language, we compared the behaviors of multiline, single-line, arrays, and double quotes as arguments.
Let’s try using the rm command as an example.
$ \ls -1
1.txt
2.txt
3.txt
$ rm "$( \ls -1 )"
rm: cannot remove '1.txt'$'\n''2.txt'$'\n''3.txt': No such file or directory
$ rm $( \ls -1 )
$ rm $( \ls -1 | ruby -e "puts STDIN.read.gsub(/\n/, \"\s\")" )
$ rm ( $( \ls -1 ) )
bash: syntax error near unexpected token `$( \ls -1 )'
Common Errors, Mistakes, and Correct Examples
Here’s a summary of common mistakes and correct examples.
rm "$$( \ls -1 )"
rm "1.txt 2.txt 3.txt"
With rm 1.txt 2.txt 3.txt, all files would have been deleted.
This first one is a common mistake. When enclosed in double quotes, it’s treated as a single argument.
rm $$( \ls -1 )
rm 1.txt 2.txt 3.txt
The second is a typical correct example. The key point is not to enclose it in double quotes.
rm $$( \ls -1 | ruby -e "puts STDIN.read.gsub(/\n/, \"\s\")" )
rm $$( printf "\n1.txt\n2.txt\n3.txt\n" )
rm 1.txt 2.txt 3.txt
The third replaces multiline output into a single line. The arguments passed can be either multiline or single-line, meaning they can be separated by spaces or newlines. However, in either case, if you enclose the arguments in double quotes, it will be treated as a single argument and result in an error.
rm ( $$( \ls -1 ) )
rm (1.txt 2.txt 3.txt)
The fourth tried passing an array. Arrays aren’t a processing target, so it results in an error. Since there are occasional cases where you pass an array as an argument for processing, in such cases you can do it with parentheses without double quotes.