1

I have a code in which I need to run a SSH Command on an AWS Instance using JSCH Java API. Sometimes the command runs without any problems, sometimes it get stuck forever on the while block. Can someone please enlight me what could be possibly going wrong? Here is the method that executes the command (And an example of command that I run).

public boolean runSSHCommandWithTimeout(String command, int timeout) {
Session session = null;
ChannelExec channel = null;

try {
    session = initSession(true); // The initSession(true) method always returns true, with the session connected.
    channel = (ChannelExec) session.openChannel("exec");
    ((ChannelExec) channel).setCommand(command);
    channel.setInputStream(null);
    ((ChannelExec) channel).setErrStream(System.err);
    try {
        channel.connect(60000); // I try to connect to the channel 3 times.. sometimes it returns an Exception on the 3rd time, timeout request Exception
    } catch (Exception e) {
        System.out.println("e " + e.getMessage());
    }
    
    if (channel.isConnected() == false) {
        try {
            channel.connect(60000); 
        } catch (Exception e) {
            System.out.println("e2 " + e.getMessage());
        }               
    }
    
    if (channel.isConnected() == false) {
        try {
            channel.connect(60000); 
        } catch (Exception e) {
            System.out.println("e3 " + e.getMessage());
            return false;
        }
    }
    
    if (channel.isConnected())
        System.out.println("Channel connected!");

    BufferedReader in = new BufferedReader(new InputStreamReader(channel.getInputStream()));
    LocalDateTime finalTime = LocalDateTime.now().plusMinutes(timeout);
    String msg = null;
    //Sometimes it get stuck in here, but I NEVER get the see any log.... not even with System.out
    while (((msg = in.readLine()) != null) && LocalDateTime.now().isBefore(finalTime)) {
        log.info(msg); // I use a logger class, not System.out ... 
        if (LocalDateTime.now().isBefore(horaFinal) == false) {
            log.info("Aborting connection, couldn´t guarantee the execution of SSH command.");
            break;
        }
    }

    if (!LocalDateTime.now().isBefore(finalTime) && !channel.isConnected())
        return false;

    System.out.println("SSHService Command '" + command + "' success!");
    return true;
} catch (Exception e) {
    log.error("Exception SSHService runSSHCommandWithTimeout() " +  e.getMessage());
    
    return false;
}
finally {
    if (channel != null)
    {
        channel.disconnect();
    }
    
    if (session != null)
    {
        session.disconnect();
    }
}
}

Here is a command sample and how I call the method:

String command = " sudo mkdir -p /home/ubuntu/myDir";
runSSHCommandWithTimeout(command, 5);

Please, can someone help? Why I sometimes get stuck on while forever, and I can´t get any logs out of it... What is the need of the inputStream of the Channel? And finally, why sometimes it never connects to the channel?

gbossa
  • 377
  • 1
  • 3
  • 18
  • 1
    Is it still the same command? Or do some commands work and some not? Did you try using some well tested code for reading the commands output instead of your version? Like [How to read JSch command output?](https://stackoverflow.com/q/6902386/850848) – Martin Prikryl Jun 01 '22 at 13:44
  • Well, honestly I have not read that, I will, thanks. And well, usually some simples commands run, and the ones that demand more time to process, don´t. But sometimes, simples commands like the one in the example get stuck too. – gbossa Jun 01 '22 at 13:47
  • Your comment did the Trick! Your while block in that answer is very accurate! Please, write your comment as an answer here so I can accept it! – gbossa Jun 01 '22 at 14:16

0 Answers0