如何通过Java在SSH中运行多个命令?

时间:2011-09-30 13:35:26

标签: java ssh

如何使用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运行时执行时它不会。有任何建议或建议吗?

6 个答案:

答案 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/

中的SSHJ
public 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();
    }
}