如何使用Java运行时在SSH中运行多个命令?
命令: ssh user@127.0.0.1'export MYVAR = this / dir / is / cool; /运行/我的/脚本 /的MyScript; echo $ MYVAR'
@Test
public void testSSHcmd() throws Exception
{
StringBuilder cmd = new StringBuilder();
cmd.append("ssh ");
cmd.append("user@127.0.0.1 ");
cmd.append("'export ");
cmd.append("MYVAR=this/dir/is/cool; ");
cmd.append("/run/my/script/myScript; ");
cmd.append("echo $MYVAR'");
Process p = Runtime.getRuntime().exec(cmd.toString());
}
它自己的命令会起作用,但是当试图从java运行时执行时它不会。有任何建议或建议吗?
答案 0 :(得分:5)
使用较新的ProcessBuilder课程代替Runtime.exec
。您可以通过指定程序及其参数列表来构造一个,如下面的代码所示。您不需要在命令周围使用单引号。您还应该阅读stdout和stderr流以及waitFor
以完成该过程。
ProcessBuilder pb = new ProcessBuilder("ssh",
"user@127.0.0.1",
"export MYVAR=this/dir/is/cool; /run/my/script/myScript; echo $MYVAR");
pb.redirectErrorStream(); //redirect stderr to stdout
Process process = pb.start();
InputStream inputStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while((line = reader.readLine())!= null) {
System.out.println(line);
}
process.waitFor();
答案 1 :(得分:1)
您正在调用的Runtime.exec
的veriant将命令字符串拆分为多个标记,然后将这些标记传递给ssh。您需要的是可以提供字符串数组的变体之一。剥离外部引号时,将完整的远程部分放入一个参数中。实施例
Runtime.exec(new String[]{
"ssh",
"user@127.0.0.1",
"export MYVAR=this/dir/is/cool; /run/my/script/myScript; echo $MYVAR"
});
就是这样。
答案 2 :(得分:1)
如果Process
挂起,我怀疑/run/my/script/myScript
会向stderr
输出内容。您需要处理该输出以及stdout
:
public static void main(String[] args) throws Exception {
String[] cmd = {"ssh", "root@localhost", "'ls asd; ls'" };
final Process p = Runtime.getRuntime().exec(cmd);
// ignore all errors (print to std err)
new Thread() {
@Override
public void run() {
try {
BufferedReader err = new BufferedReader(
new InputStreamReader(p.getErrorStream()));
String in;
while((in = err.readLine()) != null)
System.err.println(in);
err.close();
} catch (IOException e) {}
}
}.start();
// handle std out
InputStreamReader isr = new InputStreamReader(p.getInputStream());
BufferedReader reader = new BufferedReader(isr);
StringBuilder ret = new StringBuilder();
char[] data = new char[1024];
int read;
while ((read = reader.read(data)) != -1)
ret.append(data, 0, read);
reader.close();
// wait for the exit code
int exitCode = p.waitFor();
}
答案 3 :(得分:0)
您可能需要查看JSch库。它允许您使用远程主机执行各种SSH操作,包括执行命令和脚本。
他们在此列出了示例:http://www.jcraft.com/jsch/examples/
答案 4 :(得分:0)
这是正确的方法:
Runtime rt=Runtime.getRuntime();
rt.exec("cmd.exe /c start <full path>");
例如:
Runtime rt=Runtime.getRuntime();
rt.exec("cmd.exe /c start C:/aa.txt");
答案 5 :(得分:0)
如果您使用https://github.com/shikhar/sshj/
中的SSHJpublic static void main(String[] args) throws IOException {
final SSHClient ssh = new SSHClient();
ssh.loadKnownHosts();
ssh.connect("10.x.x.x");
try {
//ssh.authPublickey(System.getProperty("root"));
ssh.authPassword("user", "xxxx");
final Session session = ssh.startSession();
try {
final Command cmd = session.exec("cd /backup; ls; ./backup.sh");
System.out.println(IOUtils.readFully(cmd.getInputStream()).toString());
cmd.join(5, TimeUnit.SECONDS);
System.out.println("\n** exit status: " + cmd.getExitStatus());
} finally {
session.close();
}
} finally {
ssh.disconnect();
}
}