Shellcheck 批准了一种将一个变量中的 2 个参数传递给 bash 脚本中的命令的方法

Shellcheck 批准了一种将一个变量中的 2 个参数传递给 bash 脚本中的命令的方法

在 bash 脚本中,我调用另一个程序,但我想使用命令行选项配置该程序。以下作品:

AREA_ARG=""
if __SOME_SETTING__ ; then
  AREA_ARG=" --area us,ca "
fi

process_data -i /some/path $AREA_ARG

即 bash 执行process_data -i /some/path, 或process_data -i /some/path --area us,ca

然而shellcheck抱怨!

$ shellcheck test.sh 

In test.sh line 7:
process_data -i /some/path $AREA_ARG
                           ^-------^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean: 
process_data -i /some/path "$AREA_ARG"

For more information:
  https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...

道理我都懂,但是我/需要要在空间上拆分的变量,以便process_data获得 2 个参数。

执行此操作的正确方法是什么bash

答案1

使用数组

这是使用数组重写的代码。也是一个工作示例(ls代替您的命令),并使用正确的变量大小写(编码标准规定大写名称是为系统保留的)。

#!/bin/bash

area_args=()
if true ; then
  area_args=(-l -a)
fi

ls "${area_args[@]}"

答案2

对于您的具体用例,有一个更简单的答案:

unset -v area
if __SOME_SETTING__; then
  area="ca,us"
fi

process_data -i /some/path ${area+ --area "$area" }

如果由于某种原因你不能使用数组,如果您需要比上述实践提供的更多控制,您可以考虑使用函数包装器。

withOptionalArea() {
  if __SOME_SETTING__; then
    "$@" --area us,ca
  else
    "$@"
  fi
}

withOptionalArea process_data -i /some/path

...但这应该只在特殊情况下才有必要。


确实,使用数组。

答案3

在变量中存储任意命令或参数的正确方法是使用数组,请参阅我们如何运行存储在变量中的命令?

但是你可以告诉 shellcheck 你喜欢它本来的样子,只要你确定它没问题(即你没有应该保持完整的空格,或者可能导致问题的全局字符,并且没有改变IFS到一些会毁掉这个的东西):

AREA_ARG=""
if __SOME_SETTING__ ; then
  AREA_ARG=" --area us,ca "
fi


# shellcheck disable=SC2086 # split on purpose
process_data -i /some/path $AREA_ARG

https://www.shellcheck.net/wiki/Directive

答案4

许多参数解析库允许您使用=符号来连接长选项名称及其值。 (这包括Gnu libc的解析器和Python的标准arg解析库。)如果您正在调用这样的程序,并且不需要更多通用性,则可以使用:

AREA_ARG=--area=us,ca

相关内容