从 perl 脚本调用系统命令打印输出并将其存储到变量中
Call system command from perl script printing the output AND storing it into a variable
我要发送命令,例如执行ping:
ping google.es -n 500
我可以执行命令:
my $command = "ping google.es -n 500";
system($command);
我会在它运行时打印输出。
我可以将它存储到一个变量中:
my $command = "ping google.es -n 500";
my $output = `$command`;
但是我怎样才能获得命令 WHILE 的输出 运行 然后在变量中使用输出?
我见过这样的解决方案,但它不起作用。它运行脚本,完成后它会打印结果:
my $variable = '';
open my $command_pipe, "-|", $command or die "Pipe from $command failed: $!";
while (<$command_pipe>) {
print $_;
$variable . = $_;
}
更新:
显示问题的示例。我有 2 个 perl 脚本,一个调用另一个:
test.pl:
use strict;
use warnings;
my $command = 'perl test2.pl';
print "Localtime: " . localtime() . "\n";
my $variable = '';
open my $command_pipe, "-|", $command or die "Pipe from $command failed: $!";
while (<$command_pipe>) {
print "[" . localtime() . "] " . $_;
$variable .= $_;
}
print "Localtime: " . localtime() . "\n";
print "Loop finished:\n$variable\n";
第二个文件test2.pl:
use strict;
use warnings;
print "Waiting 10 sec\n";
my $i = 0;
while($i < 10){
sleep(1);
print "$i\n";
$i++;
}
print "That's it!\n";
输出为:
C:\Users\****\Desktop\****>perl test.pl
Localtime: Wed Oct 17 13:47:06 2018
[Wed Oct 17 13:47:16 2018] Waiting 10 sec
[Wed Oct 17 13:47:16 2018] 0
[Wed Oct 17 13:47:16 2018] 1
[Wed Oct 17 13:47:16 2018] 2
[Wed Oct 17 13:47:16 2018] 3
[Wed Oct 17 13:47:16 2018] 4
[Wed Oct 17 13:47:16 2018] 5
[Wed Oct 17 13:47:16 2018] 6
[Wed Oct 17 13:47:16 2018] 7
[Wed Oct 17 13:47:16 2018] 8
[Wed Oct 17 13:47:16 2018] 9
[Wed Oct 17 13:47:16 2018] That's it!
Localtime: Wed Oct 17 13:47:16 2018
Loop finished:
Waiting 10 sec
0
1
2
3
4
5
6
7
8
9
That's it!
如您所见,所有内容都在第二个脚本的 10 秒后打印出来。
此代码完全符合我的预期(我稍微更改了您的 ping
调用的语法)。
#!/usr/bin/perl
use strict;
use warnings;
my $command = 'ping -c 5 google.es';
my $variable;
open my $command_pipe, "-|", $command or die "Pipe from $command failed: $!";
while (<$command_pipe>) {
print $_;
$variable .= $_;
}
print "Loop finished:\n$variable\n";
如果它不适合您,您可能 Suffering from Buffering。或者,您能给我们一个完整的、独立的程序来演示您的问题吗?
更新: 正如我上面所建议的,您正在遭受缓冲。你读过我链接到的文章了吗?您需要做的就是关闭 STDOUT 上的缓冲。
$|++;
更新 2: 明确地说,您需要将该代码放入 test2.pl
- 这是执行缓冲打印的程序,所以这就是您需要的地方关闭缓冲。
我要发送命令,例如执行ping:
ping google.es -n 500
我可以执行命令:
my $command = "ping google.es -n 500";
system($command);
我会在它运行时打印输出。
我可以将它存储到一个变量中:
my $command = "ping google.es -n 500";
my $output = `$command`;
但是我怎样才能获得命令 WHILE 的输出 运行 然后在变量中使用输出?
我见过这样的解决方案,但它不起作用。它运行脚本,完成后它会打印结果:
my $variable = '';
open my $command_pipe, "-|", $command or die "Pipe from $command failed: $!";
while (<$command_pipe>) {
print $_;
$variable . = $_;
}
更新: 显示问题的示例。我有 2 个 perl 脚本,一个调用另一个:
test.pl:
use strict;
use warnings;
my $command = 'perl test2.pl';
print "Localtime: " . localtime() . "\n";
my $variable = '';
open my $command_pipe, "-|", $command or die "Pipe from $command failed: $!";
while (<$command_pipe>) {
print "[" . localtime() . "] " . $_;
$variable .= $_;
}
print "Localtime: " . localtime() . "\n";
print "Loop finished:\n$variable\n";
第二个文件test2.pl:
use strict;
use warnings;
print "Waiting 10 sec\n";
my $i = 0;
while($i < 10){
sleep(1);
print "$i\n";
$i++;
}
print "That's it!\n";
输出为:
C:\Users\****\Desktop\****>perl test.pl
Localtime: Wed Oct 17 13:47:06 2018
[Wed Oct 17 13:47:16 2018] Waiting 10 sec
[Wed Oct 17 13:47:16 2018] 0
[Wed Oct 17 13:47:16 2018] 1
[Wed Oct 17 13:47:16 2018] 2
[Wed Oct 17 13:47:16 2018] 3
[Wed Oct 17 13:47:16 2018] 4
[Wed Oct 17 13:47:16 2018] 5
[Wed Oct 17 13:47:16 2018] 6
[Wed Oct 17 13:47:16 2018] 7
[Wed Oct 17 13:47:16 2018] 8
[Wed Oct 17 13:47:16 2018] 9
[Wed Oct 17 13:47:16 2018] That's it!
Localtime: Wed Oct 17 13:47:16 2018
Loop finished:
Waiting 10 sec
0
1
2
3
4
5
6
7
8
9
That's it!
如您所见,所有内容都在第二个脚本的 10 秒后打印出来。
此代码完全符合我的预期(我稍微更改了您的 ping
调用的语法)。
#!/usr/bin/perl
use strict;
use warnings;
my $command = 'ping -c 5 google.es';
my $variable;
open my $command_pipe, "-|", $command or die "Pipe from $command failed: $!";
while (<$command_pipe>) {
print $_;
$variable .= $_;
}
print "Loop finished:\n$variable\n";
如果它不适合您,您可能 Suffering from Buffering。或者,您能给我们一个完整的、独立的程序来演示您的问题吗?
更新: 正如我上面所建议的,您正在遭受缓冲。你读过我链接到的文章了吗?您需要做的就是关闭 STDOUT 上的缓冲。
$|++;
更新 2: 明确地说,您需要将该代码放入 test2.pl
- 这是执行缓冲打印的程序,所以这就是您需要的地方关闭缓冲。