【问题标题】:Passing an argument with single and double quotes to shell script将带有单引号和双引号的参数传递给 shell 脚本
【发布时间】:2017-10-31 01:08:08
【问题描述】:

我们正在尝试将带有单引号和双引号的参数传递给 shell 脚本并使用此参数执行。在 echo 它的打印正确但是对于我们得到的命令是“未终止的引用值”

请看脚本和参数传递方法:

[root@geopc]/root# ./myscript.sh 'localhost:9199/jmxrmi -O java.lang:type=GarbageCollector,name="PS MarkSweep" -A CollectionCount -K duration'


#!/bin/bash
out=`/usr/lib64/nagios/plugins/check_jmx -U service:jmx:rmi:///jndi/rmi://$1`
echo $1
echo $out

执行后我们得到的输出为

$1 : localhost:9199/jmxrmi -O java.lang:type=GarbageCollector,name="PS MarkSweep" -A CollectionCount -K duration

$out : JMX CRITICAL 未终止的引用值

在 Shell Script 中,我们硬编码 $1 的值,然后执行我们得到正确的结果。

我们尝试如下传递参数:

./myscript.sh 'localhost:9199/jmxrmi -O java.lang:type=GarbageCollector,name=\"PS MarkSweep\" -A CollectionCount -K duration'

在这种情况下,错误是:JMX CRITICAL Invalid character '"' in value part of property

./myscript.sh 'localhost:9199/jmxrmi -O java.lang:type=GarbageCollector,name="\"PS MarkSweep\"" -A CollectionCount -K duration'

在这种情况下,错误是 JMX CRITICAL 未终止的引用值

所以请任何人帮助我。

【问题讨论】:

  • 您是否尝试过作为单个参数传递并在调用中使用 $@ 或 $*?
  • 问题不在于传递参数,而是在脚本内部正确解释该参数。 Bash FAQ 50 在某种程度上涵盖了您在脚本中尝试执行的操作。

标签: linux bash shell


【解决方案1】:

问题是您希望变量中的引号和转义符与脚本中的引号相同。

在 Java 术语中,这与预期相同:

String input="\"foo\", \"bar\"";
String[] parameters = { input };

与此相同:

String[] parameters = { "foo", "bar" };

两种语言的真正解决方案是让输入为元素数组:

#!/bin/bash
out=`/usr/lib64/nagios/plugins/check_jmx -U service:jmx:rmi:///jndi/rmi://"$1" "${@:2}"`
echo "$1"
echo "$out"

然后运行:

./myscript.sh localhost:9199/jmxrmi -O java.lang:type=GarbageCollector,name="PS MarkSweep" -A CollectionCount -K duration

但是!!

这需要纪律和理解。

您会注意到这不是一个插入式解决方案:现在使用多个参数调用脚本。这是一个非常严格的要求。如果这个脚本被另一个程序调用,这个程序也必须意识到这一点。它需要端到端处理。

例如,如果您将其存储在配置文件中,则您有责任以可以反序列化为列表的方式序列化字符串。你不能只希望它会成功,因为它不会。与 Java 不同,混淆字符串和列表时不会出现编译器警告。

如果您不想参与其中,您可以改用eval。由于安全性和稳健性问题,这是一种不好的做法,但有时它已经足够了:

yourcommand="/usr/lib64/nagios/plugins/check_jmx -U service:jmx:rmi:///jndi/rmi://$1"
echo "$yourcommand"  # Make sure this writes the right command
eval "$yourcommand"  # This will execute it as if you copy-pasted it

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-06
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多