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

发布于 2024-12-07 13:20:47 字数 852 浏览 0 评论 0原文

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

命令: ssh [电子邮件受保护] '导出MYVAR=这个/目录/是/酷; /运行/我的/脚本 /myscript; echo $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());
  }

该命令本身可以工作,但是当尝试从 java 运行时执行时却不能。有什么建议或建议吗?

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

the command: ssh [email protected] 'export MYVAR=this/dir/is/cool; /run/my/script
/myscript; echo $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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

给妤﹃绝世温柔 2024-12-14 13:20:47

使用较新的 ProcessBuilder 类而不是 运行时.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();

Use the newer ProcessBuilder class 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 waitFor for the process to finish.

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();
神爱温柔 2024-12-14 13:20:47

如果 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();
}

If the Process just hangs I suspect that /run/my/script/myScript outputs something to stderr. You need to handle that output aswell as 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();
}
甚是思念 2024-12-14 13:20:47

您调用的 Runtime.exec 的版本将命令字符串拆分为多个令牌,然后将其传递给 ssh。您需要的是可以提供字符串数组的变体之一。将完整的远程部分放入一个参数中,同时去掉外部引号。示例

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

就是这样。

The veriant of Runtime.exec you 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(new String[]{ 
    "ssh", 
    "[email protected]", 
    "export MYVAR=this/dir/is/cool; /run/my/script/myScript; echo $MYVAR"
});

That's it.

温柔女人霸气范 2024-12-14 13:20:47

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

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

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

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

镜花水月 2024-12-14 13:20:47

这是正确的方法:

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");

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");
梦中的蝴蝶 2024-12-14 13:20:47

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

If you are using SSHJ from https://github.com/shikhar/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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文