【问题标题】:Sending a TAB control character in Java在 Java 中发送 TAB 控制字符
【发布时间】:2011-08-04 11:50:10
【问题描述】:

我正在使用 Ganymede ssh 库 (http://www.ganymed.ethz.ch/ssh2/) 连接到 ssh 服务器(显然 ;))。

通常,在使用 bash 时,当用户按下键盘上的 TAB 键时,会出现可能的命令完成列表。我想实现相同的行为,但手动发送制表符。不幸的是,我不知道如何做到这一点。发送“\t”不起作用。

编辑: 解决方案必须是通用的,它不仅适用于 bash,而且适用于其他程序,如 octave(带有命令行的开源 matlab 实现,只是 bash 命令无法使用的示例应用)。

【问题讨论】:

  • 有可能您通过此连接启动的任何 shell 都不会启用它们的交互功能,除非您的末端连接了终端。因此,要么在这些 shell 上找到一个开关,以强制它们无论如何都启用该行为,要么通过请求终端对它们“撒谎”。

标签: java ssh inputstream


【解决方案1】:

您所说的不是依赖于命令外壳吗?我认为 '\t' 不起作用,因为这是制表符,而不是制表符按键,它被您的 shell 解释为列出可能的命令完成的命令。

由于这是您要询问的库,在我看来,您想要什么,您必须自己实现,因为我认为 shell 通常会处理它。

【讨论】:

    【解决方案2】:

    你可以使用这个命令:

    compgen -c
    

    它列出了 shell 中所有可能的命令。您可以添加

    grep <something> 
    

    过滤输出

    【讨论】:

    • @Erik:看到你特别写了你想模拟一个 tab 到,你的话,"......可能的命令完成列表...... " 并看到 compgen 列出了所有可能的命令,StKiller 认为这会对您有所帮助。您可能没有很好地表达您的问题/示例。
    • 好的,我明白了。非常感谢这一点。我试图澄清我的问题,请参阅我的帖子。
    【解决方案3】:

    正如 Joachim Sauer 所说,这可能是因为您的会话没有附加终端,因此诸如 Bash 之类的程序的行为就像它们被非交互调用一样。

    Ganymede ssh 库的文档暗示调用 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 Hello\n".getBytes());
            sess.getStdin().write("ls -l /tm\t".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();
                }
            }
        };
    }
    

    【讨论】:

    • 是的,我尝试了 requestPTY 方法。但是接下来如何进行呢?我应该发送什么来发出 TAB 按键?
    • 我认为按照您的建议发送一个制表符应该可行。以下对我有用: sess = c.openSession(); sess.requestPTY("vt220"); sess.execCommand("/bin/bash"); sess.getStdin().write("ls -l /tm\t".getBytes());
    • 谢谢。效果很好。您还可以发送两次字节“9”,这是 TAB 控制字符的表示形式。我不知道为什么我自己没有找到解决方案,真的很简单;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 2019-12-28
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    相关资源
    最近更新 更多