2009-03-06 10 views
3

私は、Perl(Linux上で動作しています)からプロセスのパイプラインをセットアップしたい、別々の時間に実行される2つの部分から成り立っています。あるファイルハンドルの出力を別のファイルハンドルにリダイレクトするにはどうしたらいいですか?

例:

スタートコンシューマー・プロセス:

open(OUT, "| tar xvf - ") || die "Failed: tar: $!"; 

その後、ずっと後の生産プロセスの開始:

open(IN, "gpg -d $file |") || die "Failed: gpg: $!"; 

をが、その後何とかタールへの入力にGPGからの出力をリダイレクト。

私はループを構築することにより、これを行うことができます。

while (<IN>) { 
    print OUT; 
} 

しかし、私は何とかリダイレクトと一緒に二つのプロセスを接着できるかどうかを知りたいと思います。

+0

「または」 '||'の代わりに? 'または'は他の演算子よりも優先順位が低いので、関数内のかっこを切り捨てると、 'または'は同じ働きをしますが、 '||'関数の引数をオーバーライドし始めます。これはまれにしか必要としません。プラス、それはちょうど(私に)よりよく見えます。 –

答えて

11

2つのオープン文の前に

pipe(IN, OUT); 

を追加します。それでおしまい!あなたがより複雑な何かをしたい場合は、私はIPC ::実行CPANモジュールをお勧めします

:、それはあなたがプロセスを開始することができます

http://search.cpan.org/dist/IPC-Run/

一緒に彼らの入力と出力を結ぶ、およびロギングを追加したり、チェーン内の任意のポイントでのリダイレクション

+0

これは小さなテストスクリプトではうまく動作します。ありがとう。 #!/usr/bin/perl -w パイプ(IN、OUT)||死んだ "失敗:pipe:$!"; open(OUT、 "| cat -n")||死んだ "失敗:cat:$!\ n"; open(IN、 "netstat -n |")||死んだ "失敗:netstat:$!"; 閉じる(IN); 閉じる(OUT); – Martin

+0

私はフォークされたプロセスの親子通信のためにパイプを使用しましたが、これは決してありません。そして、それは私のために働かないようです(solarisのperl 5.8)。私はopen()のIN/OUTハンドル間のパイプを閉じる/切断していると思います。 – runrig

1

2つのプロセスが完全に無関係な場合は、FIFOを使用します。

use POSIX qw(mkfifo); 
mkfifo($path, 0700) or die "mkfifo $path failed: $!"; 

これにより、$ pathにFIFOが作成されます。今度はそのファイルに1つのプロセス書き込みを行い、他のプロセスはそのファイルから読み取ります。

1

私はProc::SafeExecが好きです。プロセスとファイルハンドルをほぼ任意の方法で簡単に結びつけることができます。ここでは例です:

use strict; 
use warnings; 

use Proc::SafeExec; 

open(my $ls, "-|", "ls", "-l") or die "Err: $!"; 
open(my $fh, ">", "tmp.txt") or die "Err: $!"; 

my $p = Proc::SafeExec->new({ 
    exec => [qw(sed -e s/a/b/)], 
    stdin => $ls, 
    stdout => $fh, 
}); 
$p->wait(); 

IPC ::ファイル名を指定して実行を見た後、それがずっと簡単になります...ここでは代わりに実行します:: IPCを使用して、同じ例です:使用しないのはなぜ

use IPC::Run qw(run); 

run [qw(ls -l)], "|", [qw(sed -e s/a/b/)], ">", "tmp.txt"; 
+0

これらのモジュールは面白そうです。私は来週にこれらを調べます。ありがとう。 – Martin

+0

はい、私はIPC :: Runが見つかるまで、入出力リダイレクション、フォーク/ exec、シグナルハンドリング、PIDモニタリングなどの作業を長時間かけて過ごしました。 (Proc :: Simpleの程度は低いが) – rjh

関連する問題