Bash quoted value可以内联使用,但不能在shell脚本内的环境变量中使用

Bash quoted value可以内联使用,但不能在shell脚本内的环境变量中使用,bash,shell,environment-variables,Bash,Shell,Environment Variables,我正在尝试在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最终得到--使用cc opt=-O0、-g和-Wno error作为单独

我正在尝试在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
最终得到
--使用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}
打印出
——使用cc opt='-O0-g-Wno error'
,这也是正确的。但是,
/configure
仍然将它们作为单独的参数接收

CC_OPTS="'-O0 -g -Wno-error'"
echo ${CC_OPTS}

我做错了什么?

您要的代码是:

CC_OPTS="-O0 -g -Wno-error"
./configure --with-cc-opt="${CC_OPTS}"
你不能仅仅把单引号放在一个字符串中,然后期望它们被解释。这就像将
+
放入一个Java字符串中,并期望它能够工作:

String s = "1+1";
System.out.println(1+1); // print 2
System.out.println(s);   // prints 1+1 instead of 2

您想要的是,
——将cc opt=-O0-g-Wno error
作为单个参数传递。所有的引号都只是为了说服shell实现这一点,并且任何引号都不应将其放入实际参数中。

您要查找的代码是:

CC_OPTS="-O0 -g -Wno-error"
./configure --with-cc-opt="${CC_OPTS}"
你不能仅仅把单引号放在一个字符串中,然后期望它们被解释。这就像将
+
放入一个Java字符串中,并期望它能够工作:

String s = "1+1";
System.out.println(1+1); // print 2
System.out.println(s);   // prints 1+1 instead of 2

您想要的是,
——将cc opt=-O0-g-Wno error
作为单个参数传递。所有的引号都只是为了说服shell实现这一点,并且任何引号都不应将其放入实际参数中。

文字引号不能替代语法引号——两者之间的区别至关重要。请参见.BTW,显示您的bug,并且
bash-xyourscript
准确地记录运行时发生的事情。(<代码>回声<代码> >,但<代码>回声< /代码>是无用的——比无用的、主动误导的——用于解释引用问题。考虑“代码> Prtff′n”——用CC opt= ${ccyopt}} /代码>更准确地显示问题。(如果您不相信<代码>回声<代码>无效,请比较<代码>回音“Fo-bar”。和
echo“foo”“bar”
——显然,这是两条含义不同的命令行,正如
ls“foo”“bar”
正在查找一个文件和
ls“foo”“bar”
正在查找两个不同的文件一样,但是从
echo
的输出中,您不会知道这一点)。(顺便说一句,如上所述,这是一个常规shell变量,而不是环境变量;shell变量存储在shell的常规内存中,而环境变量还有一个副本存储在操作系统的进程元数据中,由子进程继承,可以使用
导出
或作用域进行创建。)通过在单个命令前加前缀
var=value
,或通过程序调用
setenv()
来操作自己的环境,并扩展其子命令的环境,或通过程序在调用
execve()时显式指定环境.Literal引号不能替代语法引号——两者之间的区别至关重要。请参见.BTW,显示您的错误,
bash-x yourscript
准确记录运行时发生的情况。(<代码>回声<代码> >,但<代码>回声< /代码>是无用的——比无用的、主动误导的——用于解释引用问题。考虑“代码> Prtff′n”——用CC opt= ${ccyopt}} /代码>更准确地显示问题。(如果您不相信<代码>回声<代码>无效,请比较<代码>回音“Fo-bar”。
echo“foo”“bar”
——显然,这是两条含义不同的命令行,正如
ls“foo”“bar”
正在查找一个文件和
ls“foo”“bar”
正在查找两个不同的文件一样,但是从
echo
的输出中,您不会知道这一点)。(顺便说一句,如上所述,这是一个常规shell变量,而不是环境变量;shell变量存储在shell的常规内存中,而环境变量还有一个副本存储在操作系统的进程元数据中,由子进程继承,可以使用
导出
或作用域进行创建。)通过在单个命令前加前缀
var=value
,或通过程序调用
setenv()
来操纵它们自己的环境,并扩展它们的子命令,或通过程序在调用
execve()
时显式指定环境。