我一直在使用expectJ通过ssh(jsch)自动执行某些管理任务一段时间。它运作良好。
现在我面临一个接受控制字符触发的命令的接口。例如CTRL + B.例如。
对于非交互式自动化任务,如果我只发送unicode字符(例如
),它就可以正常工作if (request.contains("<CTRL-B>")){
request = request.replaceAll("<CTRL-B>", "\u0002");
}
问题是expectJ“interactive mode”,它将stdin和stdout连接成两个线程循环(在一个名为expectj.StreamPiper
的未记录的类中,完全相同,从一个流传输到另一个流)。
从命令行运行,我只是不知道如何从Java命令行(stdin)发送CTRL-B。
所以我的问题是:如何在交互模式下将控制字符从System.in
发送到expectJ?
聚苯乙烯。一个workaroud似乎是以某种方式“重新映射”这些控制字符。例如,一个命令由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);
}
}