1

I use sshj library for communication with linux from my Java app. And I need change user with command: su

SSHClient ssh = new SSHClient();
ssh.connect(host);
ssh.authPassword(login, password);
Session s = ssh.startSession();
Command cmd = s.exec("su my_user");
List<String> resultLines = IOUtils.readLines(cmd.getInputStream(), Charset.defaultCharset());

But, in IOUtils.readLines(cmd.getInputStream(), ... app is waits and does not go next. Thanks for any help.

Sprinter
  • 717
  • 5
  • 11
  • Does my_user have a password. If the remote is waiting you are probably waiting on console IO. – Totoro May 05 '14 at 16:12
  • No, my_user hasn't password. I probably changed user from console (PuTTY) and I didn't have any delayed. – Sprinter May 06 '14 at 07:59
  • Another possibility is you aren't in a shell, that the SSH server runs the commands (forks them) directly rather than starting a shell and forwarding all output to it. a doubt it but... Try running su with either -l or -s. – Totoro May 06 '14 at 15:44

1 Answers1

2

So, a couple of things for you to do to check this. Given what you're describing, the IOUtils.readLines() method is never returning due to the InputStream never reaching the end of stream.

The only way I've ever seen this happen is if the command you've run is stuck awaiting input. My bet would be that it's prompting for a password and is sat waiting for a response that will never come.

The following steps should help you debug:

1) Add the following line before the exec command to allocate a pseudo-terminal and ensure that any prompts will definitely be written to the InputStream:

s.allocateDefaultPTY();

2) Change your output handling to print the output character by character to the console, instead of waiting for the end of stream to be reached. Something like the following would do the trick:

    InputStream in = cmd.getInputStream();

    System.out.println("Starting SSH output.");
    int cInt;
    while ((cInt = in.read()) >= 0) {
        char c = (char) cInt;
        System.out.print(c);
    }

This will allow you to see in your console exactly what the prompt is that is causing your command to never finish executing.

If there is a prompt there, the best ways I've found to respond to them are either to:

1) use an expect script to look for the prompt and respond to it.

2) If you'd prefer to keep it within your java code, use the session.startShell() method instead of session.exec() in order to allow you to open a full shell session where you can use Input and Output streams to send your commands and monitor the output for prompts then handle them by writing your response to the provided OutputStream. This is definitely the longer and more involved approach however!

Dave Birch
  • 469
  • 4
  • 10