1

Java アプリから Linux との通信に sshj ライブラリを使用しています。そして、コマンドでユーザーを変更する必要があります:su

SSHClient ssh = new SSHClient();
ssh.connect(host);
ssh.authPassword(login, password);
Session s = ssh.startSession();
Command cmd = s.exec("su my_user");
List<String> resultLines = IOUtils.readLines(cmd.getInputStream(), Charset.defaultCharset());

しかし、 IOUtils.readLines(cmd.getInputStream(), ... app は待機していて、次に進みません。助けてくれてありがとう。

4

1 に答える 1

2

したがって、これを確認するためにいくつかのことを行う必要があります。あなたが説明していることを考えると、 InputStream がストリームの終わりに到達しないため、 IOUtils.readLines() メソッドが返されることはありません。

これが起こる唯一の方法は、実行したコマンドが入力待ちでスタックしている場合です。私の賭けは、それがパスワードを要求していて、決して来ない応答を待っているということです.

次の手順はデバッグに役立ちます。

1) exec コマンドの前に次の行を追加して、疑似端末を割り当て、プロンプトが確実に InputStream に書き込まれるようにします。

s.allocateDefaultPTY();

2) ストリームの終わりに到達するのを待つ代わりに、出力処理を変更して、出力を 1 文字ずつコンソールに出力します。次のようなものがトリックを行います:

    InputStream in = cmd.getInputStream();

    System.out.println("Starting SSH output.");
    int cInt;
    while ((cInt = in.read()) >= 0) {
        char c = (char) cInt;
        System.out.print(c);
    }

これにより、コマンドの実行が完了しない原因となっているプロンプトが何であるかをコンソールで正確に確認できます。

そこでプロンプトが表示された場合、私が見つけた最善の応答方法は次のいずれかです。

1) 期待スクリプトを使用してプロンプトを探し、それに応答します。

2) Java コード内に保持したい場合は、session.exec() の代わりに session.startShell() メソッドを使用して、入力ストリームと出力ストリームを使用できる完全なシェル セッションを開くことができるようにします。コマンドを送信し、プロンプトの出力を監視してから、提供された OutputStream に応答を書き込むことでそれらを処理します。ただし、これは間違いなくより長く、より複雑なアプローチです。

于 2014-09-26T14:46:15.857 に答える