在 perl 中,在fork()
ing 之后我可以将孩子的标准输出重定向到这样的文件
open STDOUT,">",$filename or die $!
我想知道是否有一种“复制它”的方法,将标准输出保留在父标准输出上,但也复制到指定的文件。它应该以不需要任何缓冲的方式发生,并且用户将实时看到控制台输出。这有点像 unix tee
。但理想情况下,该解决方案不会涉及任何第三方库。
在 perl 中,在fork()
ing 之后我可以将孩子的标准输出重定向到这样的文件
open STDOUT,">",$filename or die $!
我想知道是否有一种“复制它”的方法,将标准输出保留在父标准输出上,但也复制到指定的文件。它应该以不需要任何缓冲的方式发生,并且用户将实时看到控制台输出。这有点像 unix tee
。但理想情况下,该解决方案不会涉及任何第三方库。
在孩子中,执行
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;
}
}
样品运行:
$ ./拥有者 嗨! 你好 $ cat 其他输出 嗨! 你好
如果父级可以等待子级完成,则子级可以将其输出通过管道传回父级,父级负责将其打印到 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;
实际上,即使父母不能等待孩子完成,如果父母首先分叉一个孩子来执行上述逻辑,这个策略仍然有效。