Andreas
Andreas

Reputation: 5301

How to be explicit about intentional word splitting?

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

Answers (4)

Noam Manos
Noam Manos

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

Léa Gris
Léa Gris

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

KamilCuk
KamilCuk

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

chepner
chepner

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

Related Questions