Perl:在File::Remote中的单个SSH会话中解析多个文件

Perl:在File::Remote中的单个SSH会话中解析多个文件,perl,Perl,我正在使用File::Remote模块用Perl编写一个脚本。脚本需要解析多个主机中的多个文件(假设每个主机大约3个文件)。但是,每次打开文件时,脚本都会通过SSH连接到主机。我的代码如下所示: my $secure = new File::Remote(rsh => '/usr/bin/ssh', rcp => '/usr/bin/scp'); foreach $host (@hostList) { for ($number = 1; $number < 4; $nu

我正在使用File::Remote模块用Perl编写一个脚本。脚本需要解析多个主机中的多个文件(假设每个主机大约3个文件)。但是,每次打开文件时,脚本都会通过SSH连接到主机。我的代码如下所示:

my $secure = new File::Remote(rsh => '/usr/bin/ssh', rcp => '/usr/bin/scp');
foreach $host (@hostList)
{
    for ($number = 1; $number < 4; $number++)
    {
        my $logFile = "log_$number.log";
        $secure->open(HANDLE, "$host:/home/$logFile") or die;

        ...
    }
}
my$secure=newfile::Remote(rsh=>'/usr/bin/ssh',rcp=>'/usr/bin/scp');
foreach$host(@hostList)
{
对于($number=1;$number<4;$number++)
{
my$logFile=“log\u$number.log”;
$secure->open(句柄,“$host:/home/$logFile”)或die;
...
}
}
因此,如果@hostList数组中有4台主机,脚本将尝试12个SSH连接(要解析的文件总数)。然而,我发现这是低效的,我想知道我是否可以使它在每个主机或SSH会话中只需要执行一次SSH连接(因此,在本例中,总共有4个SSH连接)。是否存在这样的选择

foreach $host (@hostlist) {
    @files = map { "/home/log_$_.log" } 1 .. 3;
    open HANDLE, "/usr/bin/ssh $host cat @files |";
    # ... process HANDLE ...
}
(假设远程系统有
cat
,文件名没有空格或其他shell元字符等。)

使用:

或者使用,您甚至可以并行地从所有主机检索文件:

use Net::OpenSSH::Parallel;
$pssh = Net::OpenSSH::Parallel->new;
$pssh->add_host($_) for @hosts;
$pssh->push('*', 'scp_get', { glob => 1 }, "/home/log_*.log", "$local_path/%HOST%/");
$pssh->run;

非常感谢这段代码!还有两个问题:第一,有没有办法抑制cat命令的输出(例如,如果某些文件丢失,控制台会说文件丢失;我不希望这些文件出现在屏幕上)。第二,命令末尾的垂直条做什么?第一:
“/usr/bin/ssh$host cat@files 2>/dev/null |”
第二:它意味着从命令(管道前面)获取输出,并使命令的输出在
HANDLE
中可用。更现代的编写方法是
openhandle,“|-”,COMMAND
,但我经常使用旧方法,因为我不记得第二个参数应该是“|-”还是“-|”。哦,好的。还有一件事。与其简单地丢弃错误消息,不如将其存储到我正在运行的Perl脚本中的标量中(这样我就可以记录错误,而不是盲目地解析)。我不确定你是否能在Linux命令中做到这一点,但我还是Perl的新手,谁知道呢?没关系,我只是决定重定向输出,使其附加到我正在登录的同一个日志文件中:哦,愚蠢的我,但是如果知道我在上面的帖子中所问的是否可行,那就太好了。
use Net::OpenSSH::Parallel;
$pssh = Net::OpenSSH::Parallel->new;
$pssh->add_host($_) for @hosts;
$pssh->push('*', 'scp_get', { glob => 1 }, "/home/log_*.log", "$local_path/%HOST%/");
$pssh->run;