我在 Java 中使用 Ganymed ssh lib 连接到 Linux 机器并执行一些 unix 脚本,并显示它们的输出。
我正在运行一个父 shell 脚本,它依次运行其他几个子脚本,最后是一个 perl 脚本。对于 shell 脚本,一切都很好,但是当它到达 perl 脚本时,我停止获得任何输出。
如果我在 Linux 服务器上手动运行父脚本,我会看到 perl 的输出没有问题。
这是相关的 java 代码,连接到机器并调用 shell 脚本,并返回一个 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();
}
我的父 shell 脚本调用如下所示:
./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());
你有几个选择。
STDOUT
而不是STDERR
. 这可能很简单,就像更改warn()
为print()
.在 shell 脚本中调用 Perl 程序时,重定向STDERR
到STDOUT
.
/u01/app/perl_script.pl 2>&1
我想你也可以设置你的 Java 程序来读取STDERR
。但我不是 Java 程序员,所以我无法就最好的方法为您提供建议。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句