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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7611183/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 20:41:28  来源:igfitidea点击:

How do I run multiple commands in SSH through Java?

javassh

提问by stackoverflow

How do I run multiple commands in SSH using Java runtime?

如何使用 Java 运行时在 SSH 中运行多个命令?

the command:ssh [email protected] 'export MYVAR=this/dir/is/cool; /run/my/script /myscript; echo $MYVAR'

命令:ssh [email protected] 'export MYVAR=this/dir/is/cool; /运行/我的/脚本/我的脚本;回声 $MYVAR'

@Test
  public void testSSHcmd() throws Exception
  {
    StringBuilder cmd = new StringBuilder();

    cmd.append("ssh ");
    cmd.append("[email protected] ");
    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());
  }

The command by its self will work but when trying to execute from java run-time it does not. Any suggestions or advice?

该命令本身会起作用,但是当尝试从 java 运行时执行时它不会。有什么建议或意见吗?

回答by dogbane

Use the newer ProcessBuilderclass instead of Runtime.exec. You can construct one by specifying the program and its list of arguments as shown in my code below. You don't need to use single-quotes around the command. You should also read the stdout and stderr streams and waitForfor the process to finish.

使用较新的ProcessBuilder类而不是Runtime.exec. 您可以通过指定程序及其参数列表来构建一个,如下面的代码所示。您不需要在命令周围使用单引号。您还应该阅读 stdout 和 stderr 流并waitFor完成该过程。

ProcessBuilder pb = new ProcessBuilder("ssh", 
                                       "[email protected]", 
                                       "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();

回答by A.H.

The veriant of Runtime.execyou are calling splits the command string into several tokens which are then passed to ssh. What you need is one of the variants where you can provide a string array. Put the complete remote part into one argument while stripping the outer quotes. Example

Runtime.exec您正在调用的 veriant将命令字符串拆分为几个令牌,然后将这些令牌传递给 ssh。您需要的是可以提供字符串数组的变体之一。将完整的远程部分放入一个参数中,同时去除外部引号。例子

Runtime.exec(new String[]{ 
    "ssh", 
    "[email protected]", 
    "export MYVAR=this/dir/is/cool; /run/my/script/myScript; echo $MYVAR"
});

That's it.

而已。

回答by dacwe

If the Processjust hangs I suspect that /run/my/script/myScriptoutputs something to stderr. You need to handle that output aswell as stdout:

如果Process只是挂起,我怀疑会/run/my/script/myScriptstderr. 您需要处理该输出以及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();
}

回答by Chris Dail

You might want to take a look at the JSchlibrary. It allows you to do all sorts of SSH things with remote hosts including executing commands and scripts.

您可能想看看JSch库。它允许您对远程主机执行各种 SSH 操作,包括执行命令和脚本。

They have examples listed here: http://www.jcraft.com/jsch/examples/

他们在此处列出了示例:http: //www.jcraft.com/jsch/examples/

回答by K.Selva Kumar

Here is the right way to do it:

这是正确的方法:

Runtime rt=Runtime.getRuntime();
rt.exec("cmd.exe /c start <full path>");

For example:

例如:

Runtime rt=Runtime.getRuntime();
rt.exec("cmd.exe /c start C:/aa.txt");

回答by depicus

If you are using SSHJ from https://github.com/shikhar/sshj/

如果您使用来自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();
    }
}