1

しばらくの間、 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);
    }
}
4

0 に答える 0