实时反引输出处理

The*_*chr 3 perl

我不知道这是否可行,但我正在努力通过套接字发送命令的输出,以便在命令运行时它将显示在客户端和服务器计算机上.当我尝试使用反引号时,输出不会保存到变量中,直到命令完成,这对于运行需要很长时间的命令是不利的.

问题:是否有办法逐行扫描输出,说产生另一个过程并让它"观察"变量?

编辑:这是我尝试打开的

open DATA, "pause |" or die "Failed: $!";
while( defined(my $line = <DATA>)){
    chomp($line);
    print "$line\n";
}
Run Code Online (Sandbox Code Playgroud)

我想在命令完成之前显示输出.

ike*_*ami 6

你有正确的方法.

my @cmd = ( 'perl', '-e', '$|=1; for (1..5) { print "$_\n"; sleep 1; }' );

open(my $pipe, '-|', @cmd)
   or die("Can't launch child: $!\n");

while (defined( my $line = <$pipe> )) {
    chomp($line);
    print "<$line>\n";
}
Run Code Online (Sandbox Code Playgroud)

写入STDOUT时,大多数程序在STDOUT为终端时遇到换行符时刷新其输出("行缓冲").当STDOUT不是终端时("块缓冲"),大多数程序回退到阻止输出4 KiB或8 KiB的块.这就是为什么我必须$|=1;在上面的例子中使用子程序.

使用伪终端而不是管道使用行缓冲可以欺骗使用所述行为的程序.

my @cmd = ( 'unbuffer', 'perl', '-e', 'for (1..5) { print "$_\n"; sleep 1; }' );

open(my $pipe, '-|', @cmd)
   or die("Can't launch child: $!\n");

while (defined( my $line = <$pipe> )) {
    chomp($line);
    print "<$line>\n";
}
Run Code Online (Sandbox Code Playgroud)

IPC :: Run提供了一种创建伪终端的本机方法.

use IPC::Run qw( run );

my @cmd = ( 'perl', '-e', 'for (1..5) { print "$_\n"; sleep 1; }' );

my $buf = '';
run(\@cmd, '>pty>', sub {
    $buf .= $_[0];
    while ($buf =~ s/^(.*)\r\n//) {
        print "<$1>\n";
    }
});
Run Code Online (Sandbox Code Playgroud)