1

一段时间以来,我一直在使用expectJ通过 ssh (jsch) 自动执行一些管理任务。它一直运作良好。

现在我面临一个接受由控制字符触发的命令的界面。比如CTRL+B。

对于非交互式自动化任务,如果我只发送 unicode 字符,效果很好,比如

if (request.contains("<CTRL-B>")){
    request = request.replaceAll("<CTRL-B>", "\u0002");
}

问题是 expectJ “交互模式”,它将 stdin 和 stdout 连接到两个线程循环中(在一个名为 的未记录类expectj.StreamPiper中,正是这样做的,从一个流到另一个流的管道)。

从命令行运行,我只是不知道如何从 Java 命令行 (stdin) 发送 CTRL-B。

所以我的问题是:如何System.in在交互模式下将控制字符发送到 expectJ?

附言。似乎一种解决方法是以某种方式“重新映射”这些控制字符。例如,一个命令由 CTRL-Z 触发,但在 unix 环境中发出 CTRL-Z 将立即将当前进程发送到后台。在这种情况下,我该怎么做?

更新——我一直在用这个。我希望有更好的方法(当然,我不是在谈论重构这段代码)。片段来自expectj.StreamPiper

/**
 * Thread method that reads from the stream and writes to the other.
 */
public void run() {
    byte[] buffer = new byte[1024];
    int bytes_read;

    try {
        while(getContinueProcessing()) {
            bytes_read = inputStream.read(buffer);
            if (bytes_read == -1) {
                LOG.debug("Stream ended, closing");
                inputStream.close();
                outputStream.close();
                return;
            }

            String stringRead = new String(buffer, 0, bytes_read);
            if (stringRead.startsWith("CTRL+B")) {
                outputStream.write("\u0002".getBytes());
                sCurrentOut.append("\u0002");
                if (copyStream != null && !getPipingPaused()) {
                    copyStream.write("\u0002".getBytes());
                    copyStream.flush();
                }
            }else if (stringRead.startsWith("CTRL+Z")) {
                outputStream.write("\u001A".getBytes());
                sCurrentOut.append("\u001A");
                if (copyStream != null && !getPipingPaused()) {
                    copyStream.write("\u001A".getBytes());
                    copyStream.flush();
                }
            }else if (stringRead.startsWith("CTRL+R")) {
                outputStream.write("\u0012".getBytes());
                sCurrentOut.append("\u0012");
                if (copyStream != null && !getPipingPaused()) {
                    copyStream.write("\u0012".getBytes());
                    copyStream.flush();
                }
            }else if (stringRead.startsWith("CTRL+A")) {
                outputStream.write("\u0001".getBytes());
                sCurrentOut.append("\u0001");
                if (copyStream != null && !getPipingPaused()) {
                    copyStream.write("\u0001".getBytes());
                    copyStream.flush();
                }
            }else {
                outputStream.write(buffer, 0, bytes_read);
                sCurrentOut.append(new String(buffer, 0, bytes_read));
                if (copyStream != null && !getPipingPaused()) {
                    copyStream.write(buffer, 0, bytes_read);
                    copyStream.flush();
                }
            }
            outputStream.flush();
        }
    } catch (IOException e) {
        if (getContinueProcessing()) {
            LOG.error("Trouble while pushing data between streams", e);
        }
    } catch(IllegalBlockingModeException ignored){
        //LOG.warn("Expected exception, don't worry", ignored);
    }
}
4

0 回答 0