将带有单引号和双引号的参数传递给shell脚本

时间:2017-05-30 13:54:26

标签: linux bash shell

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

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

[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持续时间

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

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

我们尝试传递参数如下:

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

在这种情况下错误是:JMX CRITICAL字符无效'"'在物业的价值部分

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

在这种情况下,错误是JMX CRITICAL Unterminated quoted value

所以任何人都可以帮助我。

1 个答案:

答案 0 :(得分:0)

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

在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