繁体   English   中英

没有从Java调用的Perl脚本输出

[英]No output of Perl script called from Java

我在Java中使用Ganymed ssh lib连接到Linux计算机并执行一些Unix脚本,并显示其输出。

我正在运行一个父shell脚本,该脚本又会运行其他一些子脚本,最后运行一个perl脚本。 对于shell脚本来说,所有命令都可以正常工作,但是当它到达perl脚本时,我将停止获取任何输出。

如果我在Linux服务器上手动运行父脚本,我会看到perl的输出没有问题

这是相关的Java代码,连接到机器并调用shell脚本,并返回BufferedReader,从该BufferedReader可以逐行读取输出:

try {
            conn = new Connection(server);
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPublicKey(user, keyfile, keyfilePass);
            if (isAuthenticated == false) {
                throw new IOException("Authentication failed.");
            }
            sess = conn.openSession();
            if (param == null) {
                sess.execCommand(". ./.bash_profile; cd $APP_HOME; ./parent_script.sh");
            }
            else {...}

            InputStream stdout = new StreamGobbler(sess.getStdout());
            reader = new BufferedReader(new InputStreamReader(stdout));

        } catch (IOException e) {
            e.printStackTrace();
        }

我的父外壳脚本看起来像这样:

./start1  #script1 output OK
./start2  #script2 output OK
./start3  #script3 output OK
/u01/app/perl_script.pl # NO OUTPUT HERE :(

有人知道为什么会这样吗?

编辑:添加Perl脚本

#!/u01/app/repo/code/sh/perl.sh
use FindBin qw/ $Bin /;
use File::Basename qw/ dirname /;
use lib (dirname($Bin). "/pm" );
use Capture::Tiny qw/:all/;
use Data::Dumper;
use Archive::Zip;
use XML::Simple;
use MXA;
my $mx = new MXA;
chdir $mx->config->{$APP_HOME};
warn Dumper { targets => $mx->config->{RTBS} };
foreach my $target (keys %{ $mx->config->{RTBS}->{Targets} }) {
        my $cfg = $mx->config->{RTBS}->{Targets}->{$target};
        my @commands = (
                                        [
                                        ...
                                        ],
                                        [
                                        'unzip',
                                        '-o',
                                        "$cfg->{ConfigName}.zip",
                                        'Internal/AdapterConfig/Driver.xml'
                                        ],
                    [
                    'zip',
                    "$cfg->{ConfigName}.zip",
                    'Internal/AdapterConfig/Driver.xml'
                    ],
                    [
                    'rm -rf Internal'
                    ],
                    [
                    "rm -f $cfg->{ConfigName}.zip"
                    ],
                                );
        foreach my $cmnd (@commands) {
                warn Dumper { command => $cmnd };
                my ($stdout, $stderr, $status) = capture {
                        system(@{ $cmnd });
                };
                warn Dumper { stdout => $stdout,
                                                stderr => $stderr,
                                                status => $status };
        }
=pod
        warn "runnnig -scriptant /ANT_FILE:mxrt.RT_${target}argets_std.xml /ANT_TARGET:exportConfig -jopt:-DconfigName=Fixing -jopt:-DfileName=Fixing.zip');
        ($stdout, $stderr, $status) = capture {
                system('./command.app', '-scriptant -parameters');
        }
        ($stdout, $stderr, $status) = capture {
                system('unzip Real-time.zip Internal/AdapterConfig/Driver.xml');
        };
        my $xml = XMLin('Internal/AdapterConfig/MDPDriver.xml');
        print Dumper { xml => $xml };
   [[ ${AREAS} == "pr" ]] && {
      ${PREFIX}/substitute_mdp_driver_parts Internal/AdapterConfig/Driver.xml 123 controller@mdp-a-n1,controller@mdp-a-n2
   } || {
      ${PREFIX}/substitute_mdp_driver_parts Internal/AdapterConfig/Driver.xml z8pnOYpulGnWrR47y5UH0e96IU0OLadFdW/Bm controller@md-uat-n1,controller@md-uat-n2
   }
   zip Real-time.zip Internal/AdapterConfig/Driver.xml
   rm -rf Internal
   rm -f Real-time.zip
        print $mx->Dump( stdout => $stdout,
                                   stderr => $stderr,
                                   status => $status );
=cut
}

Perl代码中产生输出的部分是:

warn Dumper { stdout => $stdout,
              stderr => $stderr,
              status => $status };

查看warn()的文档,我们看到:

发出警告,通常将其打印到STDERR

但是您的Java程序正在从STDOUT读取。

InputStream stdout = new StreamGobbler(sess.getStdout());

您有两种选择。

  1. 更改您的Perl代码以将输出发送到STDOUT而不是STDERR 这可能很简单,例如将warn()更改为print()
  2. 在shell脚本中调用Perl程序时, STDERR重定向到STDOUT

     /u01/app/perl_script.pl 2>&1 

我想您也可以将Java程序设置为也可以从STDERR读取。 但是我不是Java程序员,所以我无法为您提供最佳的建议。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM