Reputation: 5301
I'm running shellcheck on my scripts and often get this warning (which in this case is correct, because cd foo bar baz
makes no sense):
cd ${SOME_DIR} || exit 1
^-- SC2046: Quote this to prevent word splitting.
This warning is mostly a good one. One exception when the variable contains multiple arguments:
gcc ${OPTIONS} ...
^-- SC2046: Quote this to prevent word splitting.
Is there a convention for being more explicit about intentional word splitting, possibly avoiding this shellcheck warning?
Upvotes: 24
Views: 9403
Reputation: 16990
Apparently, shellcheck does not complain about the missing quotes for variables (SC2046 or SC2086), if typing unquoted ${ARGS}
using parameter expansion format:
${ARGS:+ $ARGS}
(The space after :+
is for readability).
Upvotes: 4
Reputation: 19615
Simply add double quotes when no split is the intent:
cd "${SOME_DIR}" || exit 1
Perform explicit splitting into an array:
read -ra gcc_options <<<"${OPTIONS}"
gcc "${gcc_options[@]}"
Or disable shellcheck for the next statement, indicating you reviewed the operation as conform to the intent:
# shellcheck disable=SC2046 # Intended splitting of OPTIONS
gcc ${OPTIONS}
Sometimes Reading The Fine Manual is a better option than asking here:
Shellcheck gives links to its Wiki for code inspection warnings. The SC2046 Quote this to prevent word splitting wiki entry already mentions the use of read -a
in Bash and how to disable this code inspection for specific cases with non-Bash shell grammars.
Upvotes: 29
Reputation: 141493
In any cases you showed, there is no reason not to quote expansions. Use quotes.
Is there a convention for being more explicit about intentional word splitting, possibly avoiding this shellcheck warning?
The convention would be to perform word splitting with mapfile
or read -a
.
If you really want to use word splitting, then a convention would be to add a comment explaining the reason why your code wants to depend on word splitting and then additionally you could add a warning:
# I use word splitting here, because...
# shellcheck disable=SC2046
to disable the shellcheck warning, see shellcheck/wiki/ignore.
Note: Use lower case variables in your scripts. By convention, upper case variables are used for exported variables, like PATH
PWD
UID
COLUMNS
LINES
etc.
Upvotes: -2
Reputation: 531848
In your script, comments of the form # shellcheck disable=...
will disable a particular warning.
options="a b c"
# shellcheck disable=2086
foo $options
If you are running the shellcheck
script locally, you can use the -e
option instead of adding directives to the script.
$ cat tmp.sh
#/bin/sh
options="a b c"
foo $options
$ shellcheck tmp.sh
In tmp.sh line 5:
foo $options
^------^ SC2086: Double quote to prevent globbing and word splitting.
Did you mean:
foo "$options"
For more information:
https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...
$ spellcheck -e SC2086 foo.sh
$
Upvotes: 3