一段时间以来,我一直在使用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);
}
}