如何使用csh通过perl从rsh命令返回状态

时间:2013-05-01 20:44:29

标签: perl csh

我有一个通过rsh运行命令的perl脚本,我需要在远程服务器上获取该命令的退出状态。本地和远程服务器上的shell都是csh(我无法更改)。要在远程服务器上获取退出状态,我正在运行:

my $output = `rsh myserver $command;echo $status`

$ output的值是命令的结果,但$ status的值永远不会打印出来。

我删除了rsh进行测试并得到了相同的结果。这是我的测试脚本:

#!/usr/local/bin/perl5.8

use strict;
use warnings;

my $output = `printf '';echo \$status`;
print "$command\n";
print "Returned: $output\n";

这是输出:

printf '';echo $status
Returned:

如果我将命令从输出复制并粘贴到命令行中,那么0就会打印出来,就像我期望的那样:

:>printf '';echo $status
0

知道为什么这可以通过命令行工作但不能通过perl工作吗?

2 个答案:

答案 0 :(得分:0)

perl中的反向标记运算符使用sh(或更确切地说,默认系统shell,与默认登录shell不同)来执行代码,而不是csh和{ {1}}不是$status中预定义的shell变量。

答案 1 :(得分:0)

问题1

readpipe(又名``又名反引号)使用/bin/sh执行其命令,$?使用$status代替csh

解决方案1 ​​

调整命令以使用my $status = `/bin/csh -c 'rsh myserver $command; echo $status`; die "Can't create child: $!\n if $? < 0; die "Child killed by signal ".($? & 0x7F)."\n" if $? & 0x7F; die "Child exited with exit code".($? >> 8)."\n" if $? >> 8; die "rsh exited with exit code $status\n" if $status;

my $status = `rsh myserver $command; echo $?`;
die "Can't create child: $!\n if $? < 0;
die "Child killed by signal ".($? & 0x7F)."\n" if $? & 0x7F;
die "Child exited with exit code".($? >> 8)."\n" if $? >> 8;
die "rsh exited with exit code $status\n" if $status;

解决方案2

调整为bourne shell:

my $output = `rsh myserver $command`;
die "Can't create child: $!\n if $? < 0;
die "Child killed by signal ".($? & 0x7F)."\n" if $? & 0x7F;
die "Child exited with exit code".($? >> 8)."\n" if $? >> 8;
print($output);

解决方案3

shell实际上会返回它执行的最后一个命令的退出代码,所以你不需要创建一个新的通道去抓它。

$command

这也意味着您现在可以自由捕获远程程序的输出而不受干扰。


问题2

$command的内容将由本地shell和远程shell进行插值。例如,如果echo *包含use String::ShellQuote qw( shell_quote ); my $local_command = shell_quote('rsh', 'myserver', $command); my $output = `$local_command`; die "Can't create child: $!\n if $? < 0; die "Child killed by signal ".($? & 0x7F)."\n" if $? & 0x7F; die "Child exited with exit code".($? >> 8)."\n" if $? >> 8; print($output); ,则会列出本地文件而不是远程文件。需要一些逃脱。

解决方案

{{1}}