Отправка управляющего символа табуляции в Java

#java #ssh #inputstream

#java #ssh #входной поток

Вопрос:

Я использую ssh-библиотеку Ganymede (http://www.ganymed.ethz.ch/ssh2 /) для подключения к ssh-серверу (очевидно ;)).

Обычно при использовании bash, когда пользователь нажимает клавишу TAB на клавиатуре, появляется список возможных завершений команды. Я хочу добиться такого же поведения, но отправить символ табуляции вручную. К сожалению, я не знаю, как это сделать. Отправка » t» не работает.

Редактировать: решение должно быть универсальным, которое работает не только в bash, но и в других программах, таких как octave (реализация matlab с открытым исходным кодом с командной строкой, просто пример, где команды bash не могут быть применены).

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

1. Скорее всего, любые оболочки, которые вы запускаете через это соединение, не активируют свои интерактивные функции, если на вашем конце не подключен терминал. Поэтому либо найдите переключатель в этих оболочках, чтобы заставить их в любом случае включить такое поведение, либо «соврите» им, запросив терминал.

Ответ №1:

Как сказал Иоахим Зауэр, это, вероятно, связано с тем, что к вашему сеансу не подключен терминал, поэтому такие программы, как Bash, будут вести себя так, как если бы они были вызваны неинтерактивно.

Документация для ssh-библиотеки Ganymede подразумевает, что вызов session.requestPTY(…) попросит SSH-сервер присоединить псевдо-TTY к сеансу. Это похоже на передачу флага «-t» команде ssh.

Пример кода:

 import java.io.IOException;
import java.io.InputStream;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;


public class Main {
    public static void main(String[] args) throws Exception {
        new Main().test();
    }

    private Session sess;

    public void test() throws IOException, InterruptedException {
        Connection c  = new Connection("myserver", 22);
        c.connect();
        boolean OK = c.authenticateWithPassword("user", "pass");
        if (!OK) throw new IOException("Bad password");
        sess = c.openSession();
        sess.requestPTY("vt220");
        new Thread(stdoutLogger).start();
        sess.execCommand("/bin/bash");
        Thread.sleep(2000);
        sess.getStdin().write("echo Hellon".getBytes());
        sess.getStdin().write("ls -l /tmt".getBytes());
        Thread.sleep(4000);
        sess.close();
        c.close();
    }

    Runnable stdoutLogger = new Runnable() {
        public void run() {
            InputStream is = sess.getStdout();
            int b;
            try {
                while ( (b = is.read()) != -1) {
                    System.out.println("Read "   b   " - "   (char)b);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    };
}
  

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

1. Да, я попробовал метод requestPTY. Но как тогда поступить? Что я должен отправить, чтобы выполнить нажатие клавиши TAB?

2. Я думаю, что простая отправка символа табуляции, как вы предложили, должна сработать. Для меня работает следующее: sess = c.OpenSession(); sess.requestPTY(«vt220»); sess.execCommand(«/bin/bash»); sess.getStdin().write(«ls -l /tm t».getBytes());

3. Спасибо. Это работает очень хорошо. вы также могли бы дважды отправить байт ‘9’, который является представлением символа управления табуляцией. Я не знаю, почему я сам не нашел решение, действительно простое 😉

Ответ №2:

Вы можете использовать эту команду :

 compgen -c
  

В нем перечислены все возможные команды в командной строке. Вы можете добавить

 grep <something> 
  

для фильтрации выходных данных

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

1. @Erik: видел, что вы специально написали, что хотите имитировать табуляцию , по вашим словам, «… список возможных завершений команды … » и, увидев, что в compgen перечислены все возможные команды, StKiller подумал, что это поможет вам. Вероятно, вы недостаточно четко сформулировали свой вопрос / пример.

2. Хорошо, я понимаю. Большое спасибо за замечание. Я пытаюсь прояснить свой вопрос, смотрите Мой пост.

Ответ №3:

Разве то, о чем вы говорите, не зависит от командной оболочки? Я не думаю, что ‘t’ работает, потому что это символ табуляции, а не нажатие клавиши tab, которое интерпретируется вашей командной оболочкой как команда, в которой перечислены возможные завершения команды.

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