转义参数化参数的问题

转义参数化参数的问题

我觉得真的不愿意问这个问题,因为感觉我一定错过了一些非常明显的东西。但是,我无法找到具有完全相同问题的现有问题。

我们有一个不应编辑的脚本,它在处理包含空格的参数时出现了问题。我已将问题简化为一个非常简单的可重现案例:

首先,我创建了一个简单的脚本,仅输出传递给它的命令行参数:

#!/bin/bash
for i; do
    echo $i
done

然后我定义一个将传递到命令行的环境变量

MYOPT="With Space"

然后,这是我在环境中无法更改的部分,我使用变量作为参数来调用命令。不幸的是,该变量在我们的环境中没有被引用。

./mycommand.sh $MYOPT

正如您所期望的,它的输出是:

./mycommand.sh $MYOPT
"With
Space"

如果您在上面的命令中引用该变量,它就会起作用。在查看其他类似问题时,这似乎是该问题普遍接受的解决方案。

./mycommand.sh "$MYOPT"
"With Space"

但是,正如我提到的,我们无法更改此脚本的调用方式。

我尝试在环境变量中添加额外的引号,如下所示,但这也没有帮助:

MYOPT="\"With Space\""
./mycommand.sh $MYOPT
"With
Space"

有没有一种方法可以用空格定义此环境变量,以便可以将其传递到脚本中而无需在调用中引用它?

对于那些感兴趣的人来说,这个问题就出现在我们的 RHEL7 tomcat 环境中。 JAVA_OPTS 在 tomcat.conf 中设置,并且我们有 -Dparamaters="withspaces"。 Tomcat自带的主控脚本在调用Java时没有引用这些JAVA_OPTS,从而导致了这个问题。我将问题简化为上面的简单示例。

答案1

不能返回./mycommand.sh $MYOPT到 的值MYOPT。这就是为什么你没有找到办法做到这一点:这是不可能的。mycommand.sh没有收到足够的信息来重建原始值。

例如,如果 的值为MYOPTis *,则mycommand.sh使用当前目录中的文件名列表进行调用。它无法知道这个列表是如何构建的。

如果您知道 的值MYOPT遵循某些规则那么你也许能够重建它。这些规则的简单版本是:

  • 该值不包含任何字符\[*?、制表符或换行符。
  • 该值不以空格开头或结尾,也不包含连续的空格。

在这些假设下,"$*"inmycommand.sh将为您提供 的值MYOPT。但请记住,这通常不起作用。

正确的解决方案是修复您的环境。在 shell 语言中,$MYOPT并不表示“取 的值MYOPT”,而是表示“取 的值MYOPT,根据 的值进行分割IFS,并将每个结果部分视为通配符模式,如果它至少匹配一个文件,则该通配符模式将被扩展”。写“取值MYOPT”的方法是"$MYOPT",或者更一般地使用$MYOPT 双引号内

相关内容