Nezzit Nezzit - 7 months ago 172
Java Question

Sending commands to server via JSch shell channel

I can't figure it out how I can send commands via JSch shell channel.

I do this, but it doesn't work:

JSch shell = new JSch();
String command = "cd home/s/src";
Session session = shell.getSession(username, host, port);
MyUserInfo ui = new MyUserInfo();
ui.setPassword(password);
session.setUserInfo(ui);
session.connect();

channel = session.openChannel("shell");
fromServer = new BufferedReader(new InputStreamReader(channel.getInputStream()));
toServer = channel.getOutputStream();
channel.connect();
toServer.write((command + "\r\n").getBytes());
toServer.flush();


and then I read input like this:

StringBuilder builder = new StringBuilder();

int count = 0;
String line = "";

while(line != null) {
line = fromServer.readLine();
builder.append(line).append("\n");

if (line.endsWith(".") || line.endsWith(">")){
break;
}
}
String result = builder.toString();
ConsoleOut.println(result);

Answer

If it hangs at readLine() that means either your "while" is never ending (might be unlikely considering your code), or, readLine() is waiting for its source, namely the IOstream blocks the thread cause available()!=true.

I can't quite troubleshoot your code without seeing your debug info. But as an advise, have you tried PipedIntputStream? The idea is to pipe your console input to "your" output, so that you can "write" it. To implement this, you need to initialize the in/out-put.

InputStream in = new PipedInputStream();
PipedOutputStream pin = new PipedOutputStream((PipedInputStream) in);
/**...*/
channel.setInputStream(in);
channel.connect();
/** ...*/
pin.write(myScript.getBytes());

The same goes to your question, how to read console output.

PipedInputStream pout = new PipedInputStream((PipedOutputStream) out);
/**
* ...
*/
BufferedReader consoleOutput = new BufferedReader(new InputStreamReader(pout));
consoleOutput.readLine();

And again, if you are not sure how many lines to read and thus want to use "while", make sure you do something inside while to prevent 1) busy-waiting 2) ending-condition. Example:

while(!end)
{
   consoleOutput.mark(32);
   if (consoleOutput.read()==0x03) end = true;//End of Text
   else
   { 
     consoleOutput.reset();
     consoleOutput.readLine();
     end = false;
   }
}