しばらくの間、 expectJを使用して ssh (jsch) 経由でいくつかの管理タスクを自動化してきました。それはうまくいっています。
現在、制御文字によってトリガーされるコマンドを受け入れるインターフェイスに直面しています。たとえば、CTRL+B などです。
非インタラクティブな自動化タスクの場合、次のようにユニコード文字を送信するだけでうまく機能します
if (request.contains("<CTRL-B>")){
request = request.replaceAll("<CTRL-B>", "\u0002");
}
問題は、stdin と stdout を 2 つのスレッド ループに接続するexpectJ "インタラクティブ モードexpectj.StreamPiper
" です (ドキュメント化されていない という名前のクラス内で、まさにそれを行い、1 つのストリームから別のストリームにパイプします)。
コマンド ラインから実行していますが、Java コマンド ライン (stdin) から CTRL-B を送信する方法がわかりません。
私の質問は次のとおりSystem.in
です。インタラクティブモードでexpectJに制御文字を送信するにはどうすればよいですか?
Ps。回避策の 1 つは、これらの制御文字を何らかの形で「再マップ」することのようです。たとえば、あるコマンドは 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);
}
}