无法使用 Runtime.Exec 传递远程命令 (ssh)

Posted

技术标签:

【中文标题】无法使用 Runtime.Exec 传递远程命令 (ssh)【英文标题】:cannot pass remote commnds (ssh) using Runtime.Exec 【发布时间】:2014-12-26 23:20:18 【问题描述】:

我正在尝试从我的 java 代码重新启动远程服务器。我有无密码的 ssh 设置,并且 sudoers 文件有适当的参数,因此执行系统命令不需要密码。 我从本地计算机上的“bash shell”运行以下命令,远程系统关闭并正常运行

ssh -t user1@192.168.2.125 'sudo reboot'

上述命令重新启动远程服务器而不检查任何密码;现在我通过java代码传递上面的命令(我用特殊字符包围了'sudo reboot'以便它作为一个命令)

String cmd="ssh -t user1@192.168.2.125 \'sudo reboot\'";
log.info("Executing command.."+cmd);
p = Runtime.getRuntime().exec(cmd);
//open error stream and input stream and process

但是我得到以下错误

[2014-10-30 19:07:55,593] INFO Executing command..ssh -t user1@192.168.2.125 'sudo reboot'  
[2014-10-30 19:07:57,070] ERROR ERROR while executing command: ssh -t user1@192.168.2.125 'sudo reboot'  
[2014-10-30 19:07:57,070] ERROR Pseudo-terminal will not be allocated because stdin is not a terminal.
bash: sudo reboot: command not found

我做错了什么? 我试图避免使用 3rd 方库(例如:JSch)。我正在使用 centos6 和 Java 7

解决方案

1) 按照@hcs 的建议去掉单引号。然后我收到另一个关于“.. tty..”的错误消息

2)按照链接https://serverfault.com/questions/15667/remotely-reboot-tomcat中的建议更新了sudoers文件

【问题讨论】:

尝试从'sudo reboot' 周围删除单引号,我认为这是试图运行一个中间有空格的命令,而不是运行sudoreboot 作为参数。跨度> 有些命令不能从 Java 中完成。就是这样。可能是sudo,需要安全。或重新启动,这应该没问题。 Java 无法处理 CLI 控制台所能处理的所有事情。例如。使用回车来更改输出的文本。本机应用程序可以,但 Java 一直存在这个问题。制作了几个控制台类和一个 bu Sun,但仍然缺少。 @hcs。谢谢解决了。将其发布为答案,我会接受它 【参考方案1】:

'sudo reboot' 周围删除单引号,即尝试运行中间有空格的命令,而不是运行sudo 并以reboot 作为参数。

让我感到困惑的是为什么当你直接从命令行运行它时它最初可以工作......

【讨论】:

我认为(?)存在一些错误(或对命令字符串如何从 java 内存空间传递到 ssh 的误解)。这是一个这样的讨论***.com/questions/2146727/runtime-getruntime-exec【参考方案2】:

有时我使用 exec() 方法会更幸运,该方法将字符串数组作为参数,而不是单个字符串。字符串数组允许人们更好地指定不同的参数是什么,根据我的经验,这更稳定,特别是如果你在参数中有空格的话。 所以尝试以下方法:

String[] cmd = new String[]"ssh", "-t", "user1@192.168.2.125", "sudo reboot";
Runtime.getRuntime.exec(cmd);

【讨论】:

以上是关于无法使用 Runtime.Exec 传递远程命令 (ssh)的主要内容,如果未能解决你的问题,请参考以下文章

无法通过Runtime.exec运行命令

无法在 Opensuse 上运行 Java Runtime.exec()

使用 Java Runtime.exec() 在 Hadoop 上运行命令

java Runtime.exec 异常

Runtime.exec() 的安全问题

使用 Java 的 Runtime.exec() 时如何添加超时值?