执行外部命令时如何在 Perl 中捕获大的 STDOUT 输出
How to capture large STDOUT output in Perl when executing an external command
我想获取远程位置中存在的文件名列表。
我在我的 Perl 脚本中使用了以下代码片段。
my $command = "sftp -q -o${transferAuthMode}=yes -oPort=$sftpPort ${remoteUsername}\@${remoteHost} 2>\&1 <<EOF\n" .
"cd \"${remotePath}\"\n" .
"ls -l \n" .
"quit\n" .
"EOF\n";
my @files = `$command`;
当远程位置的文件数量很大 (>500) 时,并非所有文件名都被捕获到 @files
。
当我手动执行 SFTP 并列出文件时,所有文件都被列出,但我没有通过脚本获得相同的文件。每次得到 @files
大小不同。仅在文件数量较多时出现。
我找不到这背后的原因。你能帮忙吗?
这可以在不需要任何额外包的情况下实现 module/s。我在我的 CentOS 7 服务器(Windows 虚拟机)上对此进行了测试。
我的远程主机详细信息: 我在远程主机目录中有大约 2000 个文件。 CentOS 6.8 服务器。
%_gaurav@[remotehost]:/home/gaurav/files/test> ls -lrth|head -3;echo;ls -lrth|tail -2
total 7.9M
-rw-rw-r--. 1 gaurav gaurav 35 Feb 16 23:51 File-0.txt
-rw-rw-r--. 1 gaurav gaurav 35 Feb 16 23:51 File-1.txt
-rw-rw-r--. 1 gaurav gaurav 38 Feb 16 23:51 File-1998.txt
-rw-rw-r--. 1 gaurav gaurav 38 Feb 16 23:51 File-1999.txt
%_gaurav@[remotehost]: /home/gaurav/files/test>
LocalHost 的脚本输出: 请注意我是 运行 你的命令没有 o${transferAuthMode}=yes
部分。如下所示,该脚本能够将所有结果收集到一个数组中,超过 500 个结果。
我正在打印总条目,数组中的一些特定索引号以显示结果,但请尝试使用 un-commented Dumper 行以查看完整结果。
%_STATION@gaurav * /root/ga/study/pl> ./scp.pl
Read 2003 lines from SCP command.
ArrayIndex: 2,3,1999,2000 contain:
[-rw-rw-r-- 0 501 501 36B Feb 16 23:51 File-58.txt]
[-rw-rw-r-- 0 501 501 37B Feb 16 23:51 File-129.txt]
[-rw-rw-r-- 0 501 501 38B Feb 16 23:51 File-1759.txt]
[-rw-rw-r-- 0 501 501 38B Feb 16 23:51 File-1810.txt]
%_STATION@gaurav * /root/ga/study/pl>
脚本及其工作:
#!/usr/bin/perl
use strict ;
use warnings ;
use Data::Dumper ;
my $sftp_port=22 ;
my ($user, $host) = ("gaurav","192.168.246.137") ;
my $remote_path = '/home/gaurav/files/test' ;
my @result ; # To store result
my $command = "sftp -q -oPort=$sftp_port ${user}\@${host} 2>\&1 <<EOF\n"."cd $remote_path\nls -lrth\nquit\nEOF" ;
# open the command as a file handle, read output and store it.
open FH, "$command |" or die "Something went wrong!!\n" ;
while (<FH>) {
tr/(?\r|\f|\n)//d ; # Removing any new line, carriage return or form feed.
push(@result,"\[$_\]") ;
}
close FH ;
#print Dumper @result ;
# Just for printing a little bit of results from
# the array. Following lines can be deleted.
my $total = scalar @result ;
print "Read $total lines from SCP command.\n" ;
print "\nArrayIndex: 2,3,1999,2000 contain:\n
$result[2]
$result[3]
$result[1999]
$result[2000]
" ;
另一种方法: 也可以通过制作 shell 脚本并从 perl 脚本调用它并读取其输出来解决这个问题。如下所示,我的 shell 脚本被 perl 脚本和最终输出调用。当没有太多时间直接在 perl 中执行 write/formulate 命令时,这可以用作一种快速技术。 您也可以在早期脚本中使用 qx 样式(如下所示)。
Shell 脚本 "scp.sh"
%_STATION@gaurav * /root/ga/study/pl> cat scp.sh
#!/bin/bash
sftp -oPort= @ 2>&1 <<EOF
cd
ls -l
quit
EOF
Perl 脚本“2scp.pl”
%_STATION@gaurav * /root/ga/study/pl> cat 2scp.pl
#!/usr/bin/perl
use strict ;
use warnings ;
use Data::Dumper ;
my $sftp_port=22 ;
my ($user, $host) = ("gaurav","192.168.246.137") ;
my $remote_path = '/home/gaurav/files/test' ;
# Passing arguements to shell script using concatination.
my $command = './scp.sh '." $sftp_port $user $host $remote_path" ;
my @result = qx{$command} ; # Runs the command and stores the result.
my $total = scalar @result ;
print "Read $total lines from SCP command.\n" ;
# End.
输出:
%_STATION@gaurav * /root/ga/study/pl> ./2scp.pl
Read 2004 lines from SCP command.
%_STATION@gaurav * /root/ga/study/pl>
试试看并告诉我们。
谢谢。
我想获取远程位置中存在的文件名列表。
我在我的 Perl 脚本中使用了以下代码片段。
my $command = "sftp -q -o${transferAuthMode}=yes -oPort=$sftpPort ${remoteUsername}\@${remoteHost} 2>\&1 <<EOF\n" .
"cd \"${remotePath}\"\n" .
"ls -l \n" .
"quit\n" .
"EOF\n";
my @files = `$command`;
当远程位置的文件数量很大 (>500) 时,并非所有文件名都被捕获到 @files
。
当我手动执行 SFTP 并列出文件时,所有文件都被列出,但我没有通过脚本获得相同的文件。每次得到 @files
大小不同。仅在文件数量较多时出现。
我找不到这背后的原因。你能帮忙吗?
这可以在不需要任何额外包的情况下实现 module/s。我在我的 CentOS 7 服务器(Windows 虚拟机)上对此进行了测试。
我的远程主机详细信息: 我在远程主机目录中有大约 2000 个文件。 CentOS 6.8 服务器。
%_gaurav@[remotehost]:/home/gaurav/files/test> ls -lrth|head -3;echo;ls -lrth|tail -2
total 7.9M
-rw-rw-r--. 1 gaurav gaurav 35 Feb 16 23:51 File-0.txt
-rw-rw-r--. 1 gaurav gaurav 35 Feb 16 23:51 File-1.txt
-rw-rw-r--. 1 gaurav gaurav 38 Feb 16 23:51 File-1998.txt
-rw-rw-r--. 1 gaurav gaurav 38 Feb 16 23:51 File-1999.txt
%_gaurav@[remotehost]: /home/gaurav/files/test>
LocalHost 的脚本输出: 请注意我是 运行 你的命令没有 o${transferAuthMode}=yes
部分。如下所示,该脚本能够将所有结果收集到一个数组中,超过 500 个结果。
我正在打印总条目,数组中的一些特定索引号以显示结果,但请尝试使用 un-commented Dumper 行以查看完整结果。
%_STATION@gaurav * /root/ga/study/pl> ./scp.pl
Read 2003 lines from SCP command.
ArrayIndex: 2,3,1999,2000 contain:
[-rw-rw-r-- 0 501 501 36B Feb 16 23:51 File-58.txt]
[-rw-rw-r-- 0 501 501 37B Feb 16 23:51 File-129.txt]
[-rw-rw-r-- 0 501 501 38B Feb 16 23:51 File-1759.txt]
[-rw-rw-r-- 0 501 501 38B Feb 16 23:51 File-1810.txt]
%_STATION@gaurav * /root/ga/study/pl>
脚本及其工作:
#!/usr/bin/perl
use strict ;
use warnings ;
use Data::Dumper ;
my $sftp_port=22 ;
my ($user, $host) = ("gaurav","192.168.246.137") ;
my $remote_path = '/home/gaurav/files/test' ;
my @result ; # To store result
my $command = "sftp -q -oPort=$sftp_port ${user}\@${host} 2>\&1 <<EOF\n"."cd $remote_path\nls -lrth\nquit\nEOF" ;
# open the command as a file handle, read output and store it.
open FH, "$command |" or die "Something went wrong!!\n" ;
while (<FH>) {
tr/(?\r|\f|\n)//d ; # Removing any new line, carriage return or form feed.
push(@result,"\[$_\]") ;
}
close FH ;
#print Dumper @result ;
# Just for printing a little bit of results from
# the array. Following lines can be deleted.
my $total = scalar @result ;
print "Read $total lines from SCP command.\n" ;
print "\nArrayIndex: 2,3,1999,2000 contain:\n
$result[2]
$result[3]
$result[1999]
$result[2000]
" ;
另一种方法: 也可以通过制作 shell 脚本并从 perl 脚本调用它并读取其输出来解决这个问题。如下所示,我的 shell 脚本被 perl 脚本和最终输出调用。当没有太多时间直接在 perl 中执行 write/formulate 命令时,这可以用作一种快速技术。 您也可以在早期脚本中使用 qx 样式(如下所示)。
Shell 脚本 "scp.sh"
%_STATION@gaurav * /root/ga/study/pl> cat scp.sh
#!/bin/bash
sftp -oPort= @ 2>&1 <<EOF
cd
ls -l
quit
EOF
Perl 脚本“2scp.pl”
%_STATION@gaurav * /root/ga/study/pl> cat 2scp.pl
#!/usr/bin/perl
use strict ;
use warnings ;
use Data::Dumper ;
my $sftp_port=22 ;
my ($user, $host) = ("gaurav","192.168.246.137") ;
my $remote_path = '/home/gaurav/files/test' ;
# Passing arguements to shell script using concatination.
my $command = './scp.sh '." $sftp_port $user $host $remote_path" ;
my @result = qx{$command} ; # Runs the command and stores the result.
my $total = scalar @result ;
print "Read $total lines from SCP command.\n" ;
# End.
输出:
%_STATION@gaurav * /root/ga/study/pl> ./2scp.pl
Read 2004 lines from SCP command.
%_STATION@gaurav * /root/ga/study/pl>
试试看并告诉我们。 谢谢。