我有一个需要在多个服务器上执行命令的程序。我用Runtime.getRuntime().exec();
进行了一些本地测试,结果很好。
但是一旦我想执行远程命令,它就无法工作。例如,如果我
ssh user@10.20.30.40 'touch /tmp/hello.txt'
它适用于我的终端。但它在我的Java程序中没有用:
Runtime.getRuntime().exec("ssh user@10.20.30.40 'touch /tmp/hello.txt'");
您是否有一个解决方案,可以在一个简单的main.java
中执行远程命令以进行测试(不需要日志和生产安全性等)?
谢谢!
编辑:目标是使用这样的参数执行JAR(记录并不重要,但会更好):
ssh user@10.20.30.40 '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 :(得分:1)
您的命令字符串必须先拆分为命令数组才能执行。在终端,这将由一个shell完成。单引号字符对shell具有特殊含义。命令数组如下所示:
cmdarray[0] = "ssh";
cmdarray[1] = "user@10.20.30.40";
cmdarray[2] = "touch /tmp/hello.txt";
您的exec()
版本使用另一个字符串标记生成器,将字符串拆分为空白字符。现在命令数组如下所示:
cmdarray[0] = "ssh";
cmdarray[1] = "user@10.20.30.40";
cmdarray[2] = "'touch";
cmdarray[3] = "/tmp/hello.txt'";
因此,无法在远程服务器上找到可执行文件'touch
。
ssh user@10.20.30.40 touch /tmp/hello.txt
其他特殊shell字符(如>
或&
)必须在终端转义才能传递到远程站点(不是由shell解释,而是作为ssh命令的参数传递)。如果你使用exec()
,则不必逃避这些角色。
请注意exec()
的返回类型:它是Process
对象。最好使用
Runtime.getRuntime().exec(...).waitFor();
确保命令已经完成。