![转义参数化参数的问题](https://linux22.com/image/111220/%E8%BD%AC%E4%B9%89%E5%8F%82%E6%95%B0%E5%8C%96%E5%8F%82%E6%95%B0%E7%9A%84%E9%97%AE%E9%A2%98.png)
我觉得真的不愿意问这个问题,因为感觉我一定错过了一些非常明显的东西。但是,我无法找到具有完全相同问题的现有问题。
我们有一个不应编辑的脚本,它在处理包含空格的参数时出现了问题。我已将问题简化为一个非常简单的可重现案例:
首先,我创建了一个简单的脚本,仅输出传递给它的命令行参数:
#!/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
没有收到足够的信息来重建原始值。
例如,如果 的值为MYOPT
is *
,则mycommand.sh
使用当前目录中的文件名列表进行调用。它无法知道这个列表是如何构建的。
如果您知道 的值MYOPT
遵循某些规则那么你也许能够重建它。这些规则的简单版本是:
- 该值不包含任何字符
\[*?
、制表符或换行符。 - 该值不以空格开头或结尾,也不包含连续的空格。
在这些假设下,"$*"
inmycommand.sh
将为您提供 的值MYOPT
。但请记住,这通常不起作用。
正确的解决方案是修复您的环境。在 shell 语言中,$MYOPT
并不表示“取 的值MYOPT
”,而是表示“取 的值MYOPT
,根据 的值进行分割IFS
,并将每个结果部分视为通配符模式,如果它至少匹配一个文件,则该通配符模式将被扩展”。写“取值MYOPT
”的方法是"$MYOPT"
,或者更一般地使用$MYOPT
双引号内。