如何以同步方式使用ExpectJ(等待未知内容的答案)?

时间:2012-10-15 10:54:20

标签: java ssh expectj

我的Java应用程序必须像这样工作:

  • 用户在GUI中选择bash命令,然后按“发送”。
  • 应用程序为每个命令返回不同且独立的答案 (例如,我们可以将它们存储在不同的文件中)。
  • 每个命令都以交互方式运行,而不是批量运行(它不能 比如“ls \ n pwd \ n”等)
  • 在每个命令之后,应用程序将等待并检查是否 结果还可以。如果是这样,它将发送下一个命令。
  • 我们需要在远程主机上执行su。

我使用过ExpectJ(有一点输出流)。它已经解决了1,3,4,5点。

但是第2点存在问题。在我的应用中,我需要分开回答。但我们不知道他们的长度。命令提示可以不同。任何人都知道如何“破解”ExpectJ所以它会更加同步?我正在寻找这样的行为:发送,等待完整的答案,发送,等待...我已经尝试了一些基本的同步技巧,但这通常会在超时和连接中丢失。

这个问题与我的旧问题有关:

Java library to run multiple unrelated commands on a remote server via ssh

1 个答案:

答案 0 :(得分:1)

问题基本上是expectj同时发送和侦听,在单独的线程中缓冲输入和输出,因此您必须知道响应何时结束,以便您可以分隔每个请求/响应块。如果你不关心期望“交互”模式,你可以尝试破解expect4J,期待java(https://github.com/ronniedong/Expect-for-Java)甚至apache mina sshd。

我现在面临完全相同的问题,因为我需要interactive(),所以我现在没有任何其他选择。因此,下面的解决方案并不优雅,但可以完成这项工作。太糟糕了,我们没有一个体面的期望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]);
    }