Randomly getting empty output while executing shell command via JSch

戏子无情 提交于 2019-12-22 18:24:34

问题


I am trying to execute below Linux command via JSch (space check command) using JSch:

df -h -P |awk '{print $6"  "$4}' |awk '{ if ($1 == "/On_Demand") {print}}' | awk '{print $2}' | awk '{ if ($1 ~ /M/) {print ($1*1)} else if($1 ~ /G/) {print ($1*1024)} else if($1 ~ /T/) {print ($1*1024*1024)} else if($1==0) {print ($1*1)} else if($1 ~ /K/) {print ($1/1024)} else {print ("-1")}}'

Backup command:

export ORACLE_HOME=/path/to/ora/home;export ORACLE_SID=sid;/U01/NEW_DEMO/path/to/ora/home/bin/expdp username/password directory=ON_DEMAND schemas=xyz dumpfile=expdp_xyz.dmp logfile=xyz.log;tail -n 1 /On_Demand/xyz.log

Code to read output:

public String getOutput() {
    LOGGER.debug("[getOutput]");
    StringBuffer output = new StringBuffer();
    InputStream in = null;
    if (channel != null && channel.isConnected()) {
        try {
            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;
                    output.append(new String(tmp, 0, i));
                }
                if (channel.isClosed()) {
                    LOGGER.debug("[getOutput] Channel is closed, so breaking while loop with exit code: "+channel.getExitStatus());
                    break;
                }
            }
        } catch (IOException e) {
            LOGGER.error(e.toString());
            e.printStackTrace();
        } finally {
            channel.disconnect();
        }
    } else {
        System.out.println("Channel is disconnected");
    }

    return output.toString();
}

The issue is, when I try to read the command output, many times I get the free space, but there are times I get no output.
When the SSH class is called again (like 2 or 3 times, where in a new session is established) to fire the same command, I get the output (which is strange).

The same issue is occurring in another functionality where I fire a command to take backup of an Oracle schema and when I try to read the log file generated by Oracle (both backup and tail commands are fired at once, semi colon separated), I get no output, but the log file is there. Multiple attempts to fire the same backup command gives me output.

This is a huge problem occurring in my tool since a month.

Any help regarding this will be appreciated.

Thanks in advance.


回答1:


I believe you have a race condition in your code.

If the command manages to produce an output and exit, between in.available() and channel.isClosed() tests, you lose the output.

See how the official Exec.java example re-tests the in.available() again in the channel.isClosed() block.

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){}
}


来源:https://stackoverflow.com/questions/37916619/randomly-getting-empty-output-while-executing-shell-command-via-jsch

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!