具体来说,请考虑以下情况:
MY_OPT_OPTIONS='CFLAGS="-O3 -march=native -mtune=native" CPPFLAGS="-O3 -march=native -mtune=native"'
现在我要使用以下代码执行g ++:
"$MY_OPT_OPTIONS" gcc ...
但这会导致错误:
CFLAGS="-O3: command not found
我想要的是MY_OPT_OPTIONS
变量在字面上直接扩展,并让gcc与其他命令行参数一起执行。
答案 0 :(得分:4)
通常,您不会。在参数扩展之前,可以识别出预命令分配。您将必须使用env
命令:
# Wrong, but read on...
env "$MY_OPT_OPTIONS" gcc ...
,以便首先进行扩展,然后将结果传递到env
,这将创建必要的环境。但是,env
希望将每个分配作为一个单独的参数,这意味着您需要使用一个数组才能使其正常工作。
MY_OPT_OPTIONS=(CFLAGS="-O3 -march=native -mtune=native" CPPFLAGS="-O3 -march=native -mtune=native")
env "${MY_OPT_OPTIONS[@]}" gcc ...
答案 1 :(得分:2)
除了chepner's answer与数组一起使用外部命令env
之外,另一个选择(仅依赖于shell内置功能)是使用一个函数:
with_my_options() {
CFLAGS="-O3 -march=native -mtune=native" CPPFLAGS="-O3 -march=native -mtune=native" "$@"
}
with_my_options gcc ...
...之所以有用,是因为"$@"
完全按照给定的标准计算出了您的原始命令行。
如果您真的要使用受信任的,经过审核的字符串,则也可以跳过一堆箍以使用eval
,以免产生来自以下方面的安全错误:该字符串以外的内容:
with_trusted_string() {
local trusted_prefix_str arg_str
trusted_prefix_str=$1; shift # store first argument in 'trusted_prefix_str' and pop
printf -v arg_str '%q ' "$@" # quote & concatenate remaining arguments into arg_str
eval "$trusted_prefix_str $arg_str" # evaluate resulting value
}
with_trusted_str "$MY_OPT_OPTIONS" gcc ...
以上公式为除第一个参数外的所有其他参数生成eval
-安全引号,该引数直接前缀为馈入eval
的字符串。
请注意,以上在NSA安全策略中使用的含义是“受信任”:“受信任”组件是其故障可能导致整个系统发生故障的组件。因此,信任事物本质上是不可取的。