'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?



Solution 1:[1]

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.

Solution 2:[2]

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).

Solution 3:[3]

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
$

Solution 4:[4]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 chepner
Solution 4 KamilCuk