如何明确故意分词?

How to be explicit about intentional word splitting?

我的脚本 运行 shellcheck 经常收到此警告(在这种情况下是正确的,因为 cd foo bar baz 毫无意义):

cd ${SOME_DIR} || exit 1
   ^-- SC2046: Quote this to prevent word splitting.

这个警告基本上是一个很好的警告。变量包含多个参数时的一个异常:

gcc ${OPTIONS} ...
    ^-- SC2046: Quote this to prevent word splitting.

是否有更明确的有意分词的约定,可能会避免此 shellcheck 警告?

在您的脚本中,# shellcheck disable=... 形式的注释将禁用特定警告。

options="a b c"
# shellcheck disable=2086
foo $options

如果您是 运行 本地 shellcheck 脚本,您可以使用 -e 选项而不是向脚本添加指令。

$ 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
$

当没有拆分的意图时,只需添加双引号:

cd "${SOME_DIR}" || exit 1

对数组执行显式拆分:

read -ra gcc_options <<<"${OPTIONS}"
gcc "${gcc_options[@]}"

或禁用shell检查下一条语句,表明您已将操作审核为符合意图:

# shellcheck disable=SC2046 # Intended splitting of OPTIONS
gcc ${OPTIONS}

有时R开头The Fine Manual 比在这里询问更好:

Shellcheck 提供指向其 Wiki 的链接以获取代码检查警告。 SC2046 Quote this to prevent word splitting wiki 条目已经提到在 Bash 中使用 read -a 以及如何针对非 Bash shell 语法的特定情况禁用此代码检查。

在您展示的任何情况下,没有理由不引用扩展。使用引号。

Is there a convention for being more explicit about intentional word splitting, possibly avoiding this shellcheck warning?

惯例是使用 mapfileread -a 执行分词。

如果你真的想使用分词,那么一个约定是添加一个注释来解释你的代码为什么要依赖分词的原因,然后你可以另外添加一个警告:

# I use word splitting here, because...
# shellcheck disable=SC2046

要禁用 shellcheck 警告,请参阅 shellcheck/wiki/ignore

注意:在脚本中使用小写变量。按照惯例,大写变量用于导出变量,如 PATH PWD UID COLUMNS LINES

显然,shellcheck 不会抱怨变量缺少引号(SC2046 or SC2086), if typing unquoted ${ARGS} using parameter expansion 格式:

${ARGS:+ $ARGS}

:+后面的space是为了便于阅读)。