The general rule in shell scripting is that variables should always be quoted unless there is a compelling reason not to. For more details than you probably want to know, have a look at this great Q&A: Security implications of forgetting to quote a variable in bash/POSIX shells.
Consider, however, a function like the following:
run_this(){
$@
}
Should $@
be quoted there or not? I played with it for a bit and couldn't find any case where the lack of quotes caused a problem. On the other hand, using the quotes makes it break when passing a command containing spaces as a quoted variable:
#!/usr/bin/sh
set -x
run_this(){
$@
}
run_that(){
"$@"
}
comm="ls -l"
run_this "$comm"
run_that "$comm"
Running the script above returns:
$ a.sh
+ comm='ls -l'
+ run_this 'ls -l'
+ ls -l
total 8
-rw-r--r-- 1 terdon users 0 Dec 22 12:58 da
-rw-r--r-- 1 terdon users 45 Dec 22 13:33 file
-rw-r--r-- 1 terdon users 43 Dec 22 12:38 file~
+ run_that 'ls -l'
+ 'ls -l'
/home/terdon/scripts/a.sh: line 7: ls -l: command not found
I can get around that if I use run_that $comm
instead of run_that "$comm"
, but since the run_this
(unquoted) function works with both, it seems like the safer bet.
So, in the specific case of using $@
in a function whose job is to execute $@
as a command, should $@
be quoted? Please explain why it should/shouldn't be quoted and give an example of data that can break it.
Best Answer
The problem lies in how the command is passed to the function:
"$@"
should be used in the general case where yourrun_this
function is prefixed to a normally written command.run_this
leads to quoting hell:I'm not sure how I should pass a filename with spaces to
run_this
.