Perl,重定向标准输出,但保持父级

时间:2010-07-19 18:48:22

标签: perl io-redirection tee

在perl中,在fork()之后我可以将孩子的标准输出重定向到这样的文件

open STDOUT,">",$filename or die $!

我想知道是否有“复制它”的方法,将stdout保留在父级的标准输出上,但也复制到指定的文件。它应该以不需要任何缓冲的方式发生,并且用户将实时看到控制台输出。这有点像unix tee。但理想情况下,解决方案不会涉及任何第三方库。

2 个答案:

答案 0 :(得分:3)

在孩子中,执行

open STDOUT, "|-", "tee", $output
  or die "$0: failed to start tee: $!";

如果您出于某种原因不想使用tee,可以通过open STDOUT, "|-"分拣另一个孩子来使用穷人的版本,并在孙:

#! /usr/bin/perl

use warnings;
use strict;

my $pid = fork;
die "$0: fork: $!" unless defined $pid;

if ($pid) {
  waitpid $pid, 0;
}
else {
  my $pid = open STDOUT, "|-";
  die "$0: fork: $!" unless defined $pid;
  select STDOUT; $| = 1;  # disable STDOUT buffering
  if ($pid) {
    print "Hiya!\n";
    system "echo Howdy";
    close STDOUT or warn "$0: close: $!";
    exit 0;
  }
  else {
    open my $fh, ">", "/tmp/other-output" or die "$0: open: $!";
    my $status;
    while ($status = sysread STDIN, my $data, 8192) {
      syswrite $fh, $data and print $data or die "$0: output failed: $!";
    }
    die "$0: sysread: $!" unless defined $status;
    close $fh or warn "$0: close: $!";
    exit 0;
  }
}

示例运行:

$ ./owntee 
Hiya!
Howdy

$ cat other-output 
Hiya!
Howdy

答案 1 :(得分:0)

如果父母可以等待孩子完成,孩子可以将其输出回送给父母,父母负责将其打印到STDOUT和目标文件:

open my $destfile, '>', $path or die "Can't open destination file: $!\n";

my $pid = open my $child, '-|';
defined $pid or die "Can't fork: $!\n";

if ($pid == 0) {
    # Child process:
    print "I'm the child!\n";
    close $destfile;
    #  do whatever
    exit;
}

# Parent process:

while (<$child>) {
    print STDOUT    $_;
    print $destfile $_;
}

close $child;
close $destfile;

实际上,即使父母不能等待孩子完成,如果父母第一次分叉孩子来执行上述逻辑,这种策略仍然有效。