【发布时间】:2017-09-21 02:52:38
【问题描述】:
我正在尝试在 bash 脚本中运行它。
./configure --with-cc-opt='-O0 -g -Wno-error'
但 '-O0 -g -Wno-error' 部分作为变量传入。请注意,如果没有变量,上述工作就可以正常工作。
如果我用这个
CC_OPTS="'-O0 -g -Wno-error'"
./configure --with-cc-opt=${CC_OPTS}
就像单引号中的值被拆分,./configure 最终得到 --with-cc-opt=-O0、-g 和 -Wno-error 作为单独的参数。
CC_OPTS="'-O0 -g -Wno-error'"
echo ${CC_OPTS}
打印出'-O0 -g -Wno-error',并带有正确的单引号。
CC_OPTS="'-O0 -g -Wno-error'"
echo --with-cc-opt=${CC_OPTS}
打印出--with-cc-opt='-O0 -g -Wno-error',这也是正确的。但./configure 仍然将它们作为单独的参数接收。
我做错了什么?
【问题讨论】:
-
文字引号不能代替句法引号——两者之间的区别很重要。见BashFAQ #50。
-
顺便说一句,shellcheck.net 显示您的错误,
bash -x yourscript准确记录运行时发生的情况。 (echo没有,但echo无用 - 比无用、积极误导更糟糕 - 用于找出引用问题。考虑printf '<%s>\n' --with-cc-opt=${CC_OPTS}更准确地展示问题)。 -
(如果你不相信
echo没用,比较echo "foo bar"和echo "foo" "bar"-- 显然,这是两个不同的命令行,含义不同,就像ls "foo bar"是正在寻找一个文件,ls "foo" "bar"正在寻找两个不同的文件,但您不会从echo的输出中知道这一点。 -
(顺便说一下,如上所述,这是一个常规的 shell 变量,而不是环境变量;shell 变量存储在 shell 的常规内存中,而环境变量另外还有一个副本存储在操作系统的进程元数据,由子进程继承,可以使用
export创建,或者,在单个命令的范围内,通过为其添加前缀var=value,或者通过调用setenv()的程序来操作它们自己的环境,并通过扩展名,他们的孩子的扩展名,或者通过调用execve()时显式指定环境的程序。
标签: bash shell environment-variables