How to use ExpectJ in synchronized way (waiting for answer with unknown content ) ?

1k views Asked by At

My Java application has to work like this:

  • User select bash commands in GUI and press "send."
  • Application return distinct and independent answers for each command (e.g. we could store them in different files).
  • Commands each run interactively, not in a batch (it can't be something like "ls\n pwd \n" etc)
  • After each command, the application will wait and check if the results are ok. If so, it will send the next command.
  • We need to execute su on the remote host.

I've used ExpectJ (with a little hack of output stream). It has resolved points 1,3,4,5.

But there is a problem with point 2. In my app I need to get separated answer. But we will not know their length. Command prompts can be different. Anyone knows how to "hack" ExpectJ so it will be some how more synchronized? I am looking for acting like this : send , wait for full answer, send, wait... I've tried some basic synchronization tricks but this end in timeouts and connection lost usually.

This question is related to my older one :

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

1

There are 1 answers

0
AudioBubble On

the problem basically is that expectj sends and listens at the same time, buffering inputs and outputs in separate threads, so you have to know when the response has ended so you can delimit each request/response block. If you don't care about expect "interact" mode, you can try to hack expect4J, expect-for-java (https://github.com/ronniedong/Expect-for-Java) or even apache mina sshd.

I am facing exactly the same problem right now, and since I need interact(), I don't have any other option right now. So, this solution below is not elegant, but may do the job. Too bad we don't have a decent expect java implementation. I hope we will in java 8, when (I hope) we'll have closure.

    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]);
    }