Как запустить несколько команд в SSH через Java? - PullRequest
2 голосов
/ 30 сентября 2011

Как запустить несколько команд в SSH с использованием среды выполнения Java?

команда: 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 ]

5 голосов
/ 30 сентября 2011

Используйте более новый 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 голос
/ 30 сентября 2011

Если 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();
}
1 голос
/ 30 сентября 2011

Вериант Runtime.exec, который вы вызываете, разбивает командную строку на несколько токенов, которые затем передаются в ssh.Что вам нужно, это один из вариантов, где вы можете предоставить массив строк.Поместите полную удаленную часть в один аргумент, удаляя внешние кавычки.Пример

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

Вот и все.

0 голосов
/ 22 мая 2012

Если вы используете SSHJ с 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();
    }
}
0 голосов
/ 23 апреля 2012

Вот правильный способ сделать это:

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");
0 голосов
/ 30 сентября 2011

Возможно, вы захотите взглянуть на библиотеку JSch . Он позволяет вам выполнять всевозможные SSH-операции с удаленными узлами, включая выполнение команд и сценариев.

У них есть примеры, перечисленные здесь: http://www.jcraft.com/jsch/examples/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...