通过JSch执行shell命令时随机获取空输出 [英] Randomly getting empty output while executing shell command via JSch

查看:422
本文介绍了通过JSch执行shell命令时随机获取空输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

备份命令:

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次,在新会话中建立的地方)触发相同的命令,我得到输出(这很奇怪)。

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).

同样的问题出现在另一个功能中,我发出命令来备份Oracle模式,当我尝试读取Oracle生成的日志文件(备份和尾部命令都是一次触发,半冒号分开),我没有输出,但是日志文件就在那里。多次尝试触发相同的备份命令会给我输出。

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.

提前致谢。

推荐答案

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

I believe you have a race condition in your code.

如果命令设法生成输出并退出,则在 in.available()和 channel.isClosed()测试,你输掉了。

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

了解官方 Exec.java 示例再次在 channel.isClosed() in.available() $ c>阻止。

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

这篇关于通过JSch执行shell命令时随机获取空输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆