2017-04-10 87 views
2

我有一個程序需要在多個服務器上執行命令。我用Runtime.getRuntime().exec();做了一些本地測試,它工作得很好。Java在遠程服務器上執行帶有參數的JAR

但是,一旦我想執行遠程命令,它不起作用。例如,如果我做

ssh [email protected] 'touch /tmp/hello.txt' 

它在我的終端工作。不過,這並不在我的Java程序一起工作:

Runtime.getRuntime().exec("ssh [email protected] 'touch /tmp/hello.txt'"); 

你有一個簡單的main.java用於測試目的執行遠程命令的解決方案(無需日誌和安全生產,所有的)?

謝謝!

編輯:我們的目標是執行一個JAR,像這樣的參數(日誌沒有真正的問題,但會更好):

ssh [email protected] 'java -jar -Dbroker-ip=10.20.30.41 -Dtopic=topic -Dpartition-number=32 -Dthread=8 -Dsource=/tmp/hour_moves /opt/Produce.jar > /tmp/logThread1 &' 
+0

您是否試過將命令封裝到bash腳本中並調用它? –

+0

是的,它的工作原理。但如果可能的話,我想在不在本地服務器上編寫文件的情況下執行此操作。 – user1484901

+0

我的意思是運行類似於'Runtime.getRuntime()。exec(「myscript.sh'」);'? exec()在Java上更爲奇怪。我總是回到這篇文章:http://www.javaworld.com/article/2071275/core-java/when-runtime-exec---won-t.html –

回答

1

你的命令字符串之前必須分成命令陣列它可以被執行。在終端,這將由一個shell完成。單引號字符對shell有特殊意義。該命令陣列將是這樣的:

cmdarray[0] = "ssh"; 
cmdarray[1] = "[email protected]"; 
cmdarray[2] = "touch /tmp/hello.txt"; 

你的exec()版本使用另一個字符串標記,在分裂空格字符的字符串。現在命令陣列看起來像這樣:

cmdarray[0] = "ssh"; 
cmdarray[1] = "[email protected]"; 
cmdarray[2] = "'touch"; 
cmdarray[3] = "/tmp/hello.txt'"; 

所以可執行'touch不能在遠程服務器上找到。

順便說一句:沒有必要使用單引號。這應該也可以工作(在這兩種情況下):像>&

ssh [email protected] touch /tmp/hello.txt 

其他特殊shell字符必須在終端進行轉義傳遞到遠程站點(而不是由shell來解釋,但通過爲參數ssh命令)。如果你使用exec(),你不必逃避這個角色。

請注意exec()的返回類型:它是一個Process對象。最好使用

Runtime.getRuntime().exec(...).waitFor(); 

確定該命令已完成。

相關問題