2017-05-30 98 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 
相關問題