JSch channel.disconnect防止打印日志(JSch channel.disconn

2019-09-29 06:09发布

我使用JSch和使用JSch通道打印命令日志在我的日志文件上传到远程计算机上运行shell脚本。 问题是,在脚本结束,我做了channel.disconnect和断开连接后不久,System.out中停止打印到日志文件。 下面是代码:

private int runShellScript(HashMap bundleDetails) {
        int exitStatus = -1;
        Channel channel = null;
        Session session = null;
        try {
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");

            String host = (String) bundleDetails.get("host");
            String userName = (String) bundleDetails.get("userName");
            String password = (String) bundleDetails.get("password");
            String bundleName = findFileName((String) bundleDetails.get("bundleName"));

            String sourceLocation = (String) bundleDetails.get("sourceLocation");
            String logFileName = findFileName((String) bundleDetails.get("logFileName"));

            String targetLocation = (String)bundleDetails.get("targetLocation");            

            String command1 = "sh "+(String) bundleDetails.get("targetIndexerLocation") + (String) bundleDetails.get("deployScript")+" "+
                                    targetLocation + bundleName + " " +
                                    targetLocation + logFileName;
            JSch ssh = new JSch();
            session = ssh.getSession(userName, host, 22);
            session.setConfig(config);
            session.setPassword(password);
            session.connect();

            channel = session.openChannel("exec");
            ((ChannelExec)channel).setCommand(command1);
            channel.setInputStream(null);
            ((ChannelExec)channel).setErrStream(System.err);
            InputStream in=channel.getInputStream();
            channel.connect();
            byte[] tmp=new byte[1024];
            while(true){
                //System.out.println("inside while second");
                  while(in.available()>0){
                    int i=in.read(tmp, 0, 1024);
                    if(i<0)break;
                    System.out.print("*****NEW ONE*****$$$$$**$$########"+new String(tmp, 0, i));
              }
                  if(channel.isClosed()){
                      exitStatus = channel.getExitStatus();
                     System.out.println("Before Disconnected Here exit-status: "+exitStatus);
                      channel.disconnect();
                    System.out.println("Disconnected Here exit-status: "+exitStatus);
                    break;
                  }
            }       
            //logger("runShellScript", "END");
            System.out.println("***** out of infinite loop");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Copy to remote location failed.... ");
        }finally{
            System.out.println("finally DISCONNECT channel and session");
            if(channel!=null && channel.isConnected()){
                channel.disconnect();
            }
            if(session!=null){
                session.disconnect();
            }           
            System.out.println("finally DISCONNECTED channel and session");

        }
        System.out.println("Before return exit-status: "+exitStatus);
        return exitStatus;
    }

从日志文件中的几行:

 *****NEW ONE*****$$$$$**$$########Starting... 

断开这里退出状态前:0

如果你在我上面粘贴的方法看,打印系统输出实际上是一个正上方的“channel.disconnect”。 它下面的一个不打印! 人的运作是正确的,整体输出是我所期望

的System.out.println(“断开连接这里退出状态之前:” +退出状态);
channel.disconnect();
的System.out.println(“断开连接这里退出状态:” +退出状态);

所有的功能是正确的,整体输出是我的期望。 唯一的问题是,日志冻结。 我要去哪里错了?

编辑
此外,我不能看到从我finally块syouts!

Answer 1:

最有可能的是与此相关的线路:

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

通过这样做,你已经追平了System.err的流通道流。 和每个文档,默认情况下,数据流时,信道被断开闭合。 你不说你是运行在什么平台上,但我想大多数平台连接System.err的和System.out的在某些方面,所以Jsch是最有可能关闭的System.out时断开连接。 您可能会尝试这样做是为了防止JSch从关闭流:

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

的Javadoc

即使不工作,虽然,我认为到System.err的这样挂钩是一个有点冒险。 我认为更安全的设计将是创建直接,不通过System.err的写日志文件的流。



Answer 2:

这是因为

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

而当你被断开通道,连接流也被切断。

所以,请断开通道之前写如下的语句:

((ChannelExec)channel).setErrStream(null);


文章来源: JSch channel.disconnect prevent logs from printing
标签: java ssh jsch