【问题标题】:quoted value works inline, but not in an environment variable inside shell script [duplicate]引用的值内联工作,但不在shell脚本内的环境变量中[重复]
【发布时间】: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


【解决方案1】:

你要的代码是:

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

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

【讨论】:

    猜你喜欢
    • 2021-07-25
    • 2014-04-06
    • 2022-11-27
    • 2015-03-02
    • 2020-12-21
    • 1970-01-01
    • 2022-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多