0

私のJavaアプリケーションは次のように動作する必要があります:

  • ユーザーは GUI で bash コマンドを選択し、「送信」を押します。
  • アプリケーションは、コマンドごとに個別の独立した回答を返します (たとえば、それらを別のファイルに保存できます)。
  • コマンドはそれぞれ、バッチではなく対話的に実行されます (「ls\n pwd \n」などのようなものにはできません)
  • 各コマンドの後、アプリケーションは待機し、結果が問題ないかどうかを確認します。その場合、次のコマンドを送信します。
  • リモートホストで su を実行する必要があります。

私はExpectJを使用しました(出力ストリームを少しハックしました)。ポイント1、3、4、5を解決しました。

しかし、ポイント 2 には問題があります。私のアプリでは、個別の回答を得る必要があります。しかし、それらの長さはわかりません。コマンド プロンプトは異なる場合があります。誰かがExpectJを「ハック」する方法を知っているので、もう少し同期されますか? 私は次のように行動することを探しています:送信、完全な回答を待つ、送信、待機...基本的な同期のトリックをいくつか試しましたが、これはタイムアウトで終わり、通常は接続が失われます。

この質問は私の古い質問に関連しています:

ssh 経由でリモート サーバー上で複数の無関係なコマンドを実行するための Java ライブラリ

4

1 に答える 1

1

基本的に問題は、expectj が送信とリッスンを同時に行い、入力と出力を別々のスレッドでバッファリングすることです。そのため、応答がいつ終了したかを把握して、各要求/応答ブロックを区切ることができるようにする必要があります。「対話」モードを期待する必要がない場合は、expect4J、expect-for-Java ( https://github.com/ronniedong/Expect-for-Java )、または apache mina sshd をハックしてみてください。

私は今、まったく同じ問題に直面しています.interact()が必要なので、今のところ他に選択肢はありません. したがって、以下のこのソリューションはエレガントではありませんが、うまくいく可能性があります。残念なことに、適切な Java 実装が期待できません。Java 8 で、(できれば) 閉鎖されることを願っています。

    ExpectJ ex = new ExpectJ(50);
    Spawn spawn = ex.spawn(new SshSpawn("192.168.56.101", 22, "alice", "password"));
    String command = "hostname -s;expr 123456788 + 1";
    spawn.send(command+"\n");
    spawn.expect("123456789");
    String lsResults = spawn.getCurrentStandardOutContents().split("123456788 \\+ 1\r\n")[2].split("123456789")[0];
    String[] lsRows = lsResults.split("\r\n");
    for(int i=0;i<lsRows.length;i++){
        System.out.println(i+":"+lsRows[i]);
    }
于 2013-04-02T12:16:42.553 に答える