简体   繁体   中英

Jsch “exec” channel does not close automatically after executing long running command

I am running a command through JSch, which just executes a script and which has a command that performs some operation for a long time.


The scenario is that the script has a command that does not print its output to the console rather it appends it to some file. This command takes a long time (More than 1 hour) without printing anything to the console.


The issue now is that the command and the script are completed (Checked in the server file in which output is printed) but nothing gets printed on the console and the channel is also not closed which is my exit condition thus resulting in a hang state since there is no command to execute and channel is not closed.

Please find code snippet below:

channel = session.openChannel("exec");
((ChannelExec) channel).setErrStream(error_stream, true);
((ChannelExec) channel).setCommand(command);
channel.setInputStream(null);       
channel.connect(TIMEOUT_VALUE);
InputStream in = channel.getInputStream();
byte[] tmp = new byte[1024];
while (true) {
    while (in.available() > 0) {
        int i = in.read(tmp, 0, 1024);
        if (i < 0) {
            break;
        }
        print(new String(tmp, 0, i));
    }
    if (channel.isClosed()) {
        print("exit-status: " + channel.getExitStatus());
        break;
    }
    try {
        Thread.sleep(500);
    } catch (InterruptedException ee) {
        logger.error(ee.toString());
    }
}
channel.disconnect();

I need to find out why the channel is not being closed.

Note:

  1. After the successful command execution is completed, the session is not present on Server -- checked using ps fx

  2. This issue is only reproducible when the command runs without consoling to the output for at least an hour


Sample command:

echo "start"
sleep 3700s
echo "end"
touch endFile.sh

In the above script, the "start is printed to the console, but "end" is not printed, however the endFile.sh is created on the server, indicating the execution is complete

Try below code, working for me

Channel channel=session.openChannel("exec");


      ((ChannelExec)channel).setCommand(command);


      channel.setInputStream(null);

      ((ChannelExec)channel).setErrStream(System.err);

      //To print the result on the console using below 3 line

      byte[] bytes = command.getBytes();   //To print the result
      ByteArrayInputStream bais=new ByteArrayInputStream(bytes);//To print the result
      channel.setInputStream(bais);//To print the result

      InputStream in=channel.getInputStream();



      channel.connect();
     channel.setOutputStream(System.out);//To print the result
      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);
      e.printStackTrace();
    }
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM