Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending commands to server via JSch shell channel

Tags:

java

ssh

jsch

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); 
like image 769
Nezzit Avatar asked Nov 16 '10 13:11

Nezzit


2 Answers

Try this:

JSch jsch = new JSch();  try {   Session session = jsch.getSession("root", "192.168.0.1", 22);   java.util.Properties config = new java.util.Properties();   config.put("StrictHostKeyChecking", "no");   session.setConfig(config);    session.connect();    String command = "lsof -i :80";   Channel channel = session.openChannel("exec");   ((ChannelExec) channel).setCommand(command);   channel.setInputStream(null);   ((ChannelExec) channel).setErrStream(System.err);   InputStream in = channel.getInputStream();    channel.connect();    byte[] tmp = new byte[1024];   while (true)   {     while (in.available() > 0)     {       int i = in.read(tmp, 0, 1024);       if (i < 0)         break;       System.out.print(new String(tmp, 0, i));     }     if (channel.isClosed())     {       System.out.println("exit-status: " + channel.getExitStatus());       break;     }     try     {       Thread.sleep(1000);     }     catch (Exception ee)     {     }   }    channel.disconnect();   session.disconnect(); } catch (Exception e) {   System.out.println(e.getMessage()); } 
like image 188
Michael Cheremuhin Avatar answered Sep 20 '22 07:09

Michael Cheremuhin


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 advice, 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;    } } 
like image 45
nilbot Avatar answered Sep 24 '22 07:09

nilbot