通过JSch执行shell命令时随机获取空输出

我试图通过JSch(空间检查命令)使用JSch在Linux命令下执行:

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")}}' 

备份命令:

 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 

读取输出的代码:

 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(); } 

问题是,当我尝试读取命令输出时,很多次我获得了可用空间,但有时我没有输出。
当再次调用SSH类(如2或3次,在新会话中建立的位置)来触发相同的命令时,我得到输出(这很奇怪)。

同样的问题出现在另一个function中,我发出命令来备份Oracle模式,当我尝试读取Oracle生成的日志文件时(备份和尾部命令都被立即触发,半冒号分开),我得到了没有输出,但日志文件在那里。 多次尝试触发相同的备份命令可以输出。

这是一个月以来我的工具中出现的一个大问题。

任何有关这方面的帮助将不胜感激。

提前致谢。

我相信你的代码中存在竞争条件。

如果命令设法生成输出并退出,则在in.available()channel.isClosed()测试之间,您将丢失输出。

查看官方Exec.java示例如何在channel.isClosed()块中再次重新测试in.available()

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