2017-05-30 97 views
0

我们试图将带单引号和双引号的参数传递给shell脚本并使用此参数执行。在正常,但呼应其打印的命令,我们正在为“未终止引述值”将带单引号和双引号的参数传递给shell脚本

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

[[email protected]]/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日后:本地主机:9199/jmxrmi -O java.lang中:类型= GarbageCollector,名字= “PS MarkSweep” -A CollectionCount -K持续时间

$出: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关键未知的报价值

所以任何人都请帮助我吧

+0

您是否尝试过通过单变量和使用$ @或者$ *的电话吗? –

+1

问题不在于传递参数,而是在脚本内部正确解释该参数。 [Bash FAQ 50](http://mywiki.wooledge.org/BashFAQ/050)在一定程度上涵盖了您在脚本内部要做的事情。 – chepner

回答

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 
相关问题