3

perlでは、fork()ingの後、子供のstdoutを次のようにファイルにリダイレクトできます

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

親の標準出力に標準出力を保持するだけでなく、指定されたファイルにコピーする「コピー」する方法があるかどうか疑問に思っています。これは、バッファリングを必要とせず、ユーザーがリアルタイムでコンソール出力を確認できるようにする必要があります。これは unix のようなものteeです。しかし、理想的には、ソリューションにはサードパーティのライブラリが含まれていません。

4

2 に答える 2

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;
  }
}

サンプルラン:

$ ./所有者
ひや!
こんにちは

$ cat 他の出力
ひや!
こんにちは
于 2010-07-19T21:09:43.433 に答える
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;

実際、親が子の処理が完了するのを待つことができなくても、親が最初に子をフォークして上記のロジックを実行する場合、この戦略は機能します。

于 2010-07-19T21:22:52.027 に答える