Skip to content

Running command using “exec” channel with JSch does not return any output

I am trying to execute a command on a Linux server using SSH from Android with JSch.

As far as I know I am connecting to the server, but when I attempt to retrieve the results of the command I am getting nothing.

Connect to server:

public class SSHCommand {

    public static String executeRemoteCommand(
            String username,
            String password,
            String hostname,
            int port) throws Exception {

        JSch jsch = new JSch();
        Session session = jsch.getSession(username, hostname, port);
        session.setPassword(password);

        // Avoid asking for key confirmation
        Properties prop = new Properties();
        prop.put("StrictHostKeyChecking", "no");
        session.setConfig(prop);

        session.connect();

        // SSH Channel
        ChannelExec channelssh = (ChannelExec)
                session.openChannel("exec");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        channelssh.setOutputStream(baos);

        // Execute command
        channelssh.setCommand("ls");
        channelssh.connect();
        channelssh.disconnect();

        return baos.toString();
    }
}

Retrieve data:

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final String TAG = "TESTING";

        new AsyncTask<Integer, Void, Void>(){
            @Override
            protected Void doInBackground(Integer... params) {
                try {
                    Log.d(TAG, SSHCommand.executeRemoteCommand("username", "password", "192.168.0.1", 22));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
        }.execute(1);
    }
}

What am I missing here?

Answer

You disconnect immediately after you start the command, before any output is returned.

You have to wait for the “exec” channel to close (it closes once the command finishes).

See the official JSch example for the “exec” channel.

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()){
    if(in.available()>0) continue; 
    System.out.println("exit-status: "+channel.getExitStatus());
    break;
  }
  try{Thread.sleep(1000);}catch(Exception ee){}
}

Though to allow the command to reliably complete and to collect all output including the errors, see How to read JSch command output?