【问题标题】:How do I run multiple commands in SSH through Java?如何通过 Java 在 SSH 中运行多个命令?
【发布时间】:2013-07-25 21:33:40
【问题描述】:

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

命令: ssh user@127.0.0.1 'export MYVAR=this/dir/is/cool; /运行/我的/脚本 /我的脚本;回声 $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 运行时执行时却不起作用。有什么建议或建议吗?

【问题讨论】:

  • 什么不起作用?会发生什么?
  • 我喜欢 stackoverflow。谢谢大家!

标签: java ssh


【解决方案1】:

使用较新的 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();

【讨论】:

  • 嗨 dogbane 我需要在一次运行中运行多个 ssh 命令,您共享的链接对我来说不是很清楚。因此,如果您有任何明确的文件,请分享给我。谢谢
【解决方案2】:

如果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】:

    您正在调用的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"
    });
    

    就是这样。

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        这是正确的做法:

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

        【讨论】:

          【解决方案6】:

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

          【讨论】:

          • 嗨,Depicus 我需要在一次运行中运行多个 ssh 命令,您共享的链接对我来说不是很清楚。因此,如果您有任何明确的文件,请分享给我。谢谢
          • 嗨 Anand,基本上每个命令都用 ;你应该很高兴。该链接对我有用。
          • 好的,Depicus。我需要使用选择查询运行多个 ssh 命令来查看状态。如果您知道如何执行选择查询,我无法执行查询,请告诉我。这里我展示了完整的命令。 cd /aep/cu/scripts/;./dbutil.ksh E1QA;select * from tgpoa01.aud_trail_dtl where AUD_TRAIL_REC_ID = '-9223372036798689753'
          • System.out.println(IOUtils.readFully(cmd.getInputStream()).toString()); 行应该返回任何输出
          猜你喜欢
          • 2010-10-08
          • 2021-05-03
          • 2013-06-05
          • 1970-01-01
          • 2014-04-07
          • 1970-01-01
          • 1970-01-01
          • 2012-03-06
          • 1970-01-01
          相关资源
          最近更新 更多