0

私は次のことができることを知っています:

open(STDOUT, "|-", "cmd");

これはおそらく次の結果になります。

  1. fork();
  2. exec("cmd");
  3. 元のプロセスの STDOUT を新しいプロセスの STDIN にリンクします。

私がやりたいのは、上記のステップ 2 ですexec()。現在のプロセスの 2 つのコピーを継続するだけで、子の STDIN が親の STDOUT にリンクされます。

これにより、次のように続行できます。

if (! $pid)
{
  # Handle data in child here
  open OUTFILE1 $file1;
  open OUTFILE2 $file2;
  my $i = 0;
  while (<>)
  {
    print (i % 2 ? OUTFILE1 : OUTFILE2) "Line $i: $_";
    ++$i;
  }
  exit;
}
else
{
  # Continue parent here
  print STDOUT "Hello World from print()";
  system("echo Hello World from system()");
}

上記のコードは、出力に行番号を追加し、このデータを行ごとに別のファイルに書き込む必要があります (少しばかげていることはわかっていますが、これは単なる例です)。

これを行う方法またはライブラリはありますか? 検討perltieしましたが、 からの結果を処理していないようでしたsystem()。そのため、実際に STDOUT をパイプするには別のプロセスが必要だと思います。

4

1 に答える 1

3

IIRC、あなたはただ欲しい

open(STDOUT, "|-", "-");

1行しかかからず、エラーレポートがopen3改善され、STDERRもキャプチャできるようになります。

use IPC::Open3 qw( open3 );
use POSIX      qw( _exit );

sub child {
   print("Hello World from print()\n");
   system("echo", "Hello World from system()");
}

my $pid = open3(
   '<&STDIN',
   \local *CHILD_STDOUT,
   '>&STDERR',
   '-',
);

if (!$pid) {
   if (eval { child(); 1 }) {
      _exit(0);
   } else {
      print(STDERR $@);
      _exit($! || ($? >> 8) || 255);
   }
}

while (<CHILD_STDOUT>) {
   ...
}

waitpid($pid, 0);
于 2013-02-15T07:53:28.323 に答える