问题
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