ssh через java

#java #ssh #jsch

#java #ssh #jsch

Вопрос:

Я использую java ssh tools, чтобы установить ssh-соединение со своей школьной учетной записью и выполнить поиск файла, а затем удалить его. Однако я создаю три функции для выполнения одного и того же действия, но с разными файлами, я ищу способ сделать это одновременно, вместо того чтобы выполнять одно за другим. Вот некоторый код. В принципе, я хочу знать, есть ли способ сделать все это через одно ssh-соединение или какой-то форк или многопоточность.

 public void updateinterval() {
    try {
        JSch jsch = new JSch();

        String user = "***********";
        String host = "********";
        Session session = jsch.getSession(user, host, 22);

        session.setPassword("*********");

        // username and password will be given via UserInfo interface.
        UserInfo userInfo = new SftpUserInfo();

        session.setUserInfo(userInfo);

        session.connect();

        // look for a file named feedinterval

        String checkfortimeupdate =
                "cd public_html/final;grep '-send' feedinterval";

        Channel channel = session.openChannel("exec");
        ((ChannelExec) channel).setCommand(checkfortimeupdate);

        // X Forwarding
        // channel.setXForwarding(true);

        // channel.setInputStream(System.in);
        channel.setInputStream(null);

        // channel.setOutputStream(System.out);

        // FileOutputStream fos=new FileOutputStream("/tmp/stderr");
        // ((ChannelExec)channel).setErrStream(fos);
        ((ChannelExec) channel).setErrStream(System.err);

        InputStream in = channel.getInputStream();

        channel.connect();

        byte[] tmp = new byte[1024];

        while (true) {
            while (in.available() > 0) {
                int i = in.read(tmp, 0, 1024);
                if (i < 0)
                    break;
                String returned = new String(tmp, 0, i);

                String argument = returned.substring(6);

                if (returned.contains("-send")) {

                    // if its there its calls the removeinterval function
                    // which removes the file it found
                    // by doing the same thing this function does but with a
                    // different ssh command

                    arduinoupdate hey = new arduinoupdate();

                    hey.removeinterval();

                    try {
                        Runtime rt = Runtime.getRuntime();

                        String[] commands = {
                                "system.exe", "-send", argument };

                        Process proc = rt.exec(commands);
                    }

                    catch (IOException e) {
                    }
                }
            }

            if (channel.isClosed()) {
                System.out.println("UpdateInterval Closed exit-status: "
                          channel.getExitStatus());
                break;
            }
            try {
                /* Thread.sleep(1000); */
            } catch (Exception ee) {
            }
        }
        channel.disconnect();
        session.disconnect();
    } catch (Exception e) {
        System.out.println(e);
    }
}
  

Комментарии:

1. пожалуйста, уделите хотя бы несколько минут правильному форматированию вашего кода. Используйте {} кнопку в редакторе и убедитесь, что ваш код доступен для чтения при предварительном просмотре.

2. Можете ли вы отформатировать свой код или удалить ненужные фрагменты?

3. Кроме того, я бы рекомендовал разложить эту функцию на небольшие методы из 1-4 строк для удобства чтения.

Ответ №1:

Если вы хотите выполнить несколько задач, возможно, ExpectJ будет работать для вас лучше. ExpectJ использует JSCH под прикрытием, так что это может облегчить вам жизнь.

 final ExpectJ expectJ = new ExpectJ();
final Spawn spawn = expectJ.spawn("host", 22, "user", "pass");
spawn.send("cd public_html/finaln");
spawn.expect("someReturn");
...
spawn.send("exitn");
spawn.expectClose();
  

Ответ №2:

Как сказали комментаторы, лучше разложить это по отдельным функциям. Тогда становится более понятным, как повторно использовать одно и то же соединение (т.Е. сеанс) для нескольких команд.

 public void updateInterval(Session s, String filename) {
    String checkfortimeupdate = "fgrep '-send' "public_html/final/"   filename   """;

    ChannelExec channel = (ChannelExec)session.openChannel("exec");
    channel.setCommand(checkfortimeupdate);

    channel.setInputStream(null);
    channel.setErrStream(System.err);
    BufferedReader in = new BufferedReader(new InputStreamReader(channel.getInputStream(), encoding));

    channel.connect();

    eatOutput(in);

    if (channel.isClosed()) {
        System.out.println("UpdateInterval Closed exit-status: "
                             channel.getExitStatus());
        break;
    }
    channel.disconnect();
}
  

Затем поместите чтение из BufferedReader (у него есть readLine метод) в метод eatOutput и используйте другой метод, который открывает сеанс и трижды вызывает метод, показанный здесь (с разными именами файлов), и снова закрывает сеанс.

Ответ №3:

Что касается использования ExpectJ, какая библиотека лучше всего подходит для использования в критически важных производственных приложениях для обеспечения ожидаемой функциональности?

Библиотека ExpectJ или Expect4J? Тем не менее, обе библиотеки используют JSch внизу! Или Apache SSHD — клиент:

 SshClient client = SshClient.setUpDefaultClient(); PipedOutputStream PipedIn...?