- ベストアンサー
Perl 内で実行される Perl が STDOUT に吐いたものを変数で受け取りたい
凄い不思議な質問タイトルになってしまいましたが……(笑) 下記のようなソースを実行したとします。 -------------------------○ source.pl open(IN, "<dest.pl"); foreach(<IN>){$s.=$_;} close(IN); eval($s); このとき、source.pl で実行される dest.pl には別の Perl プログラムが入っています。 で、dest.pl の内部にはいくつかの print ""; があって、標準出力をおこなっているわけですが、この標準出力結果を画面には出さず、source.pl 側で受け取る事はできないもんでしょうか。 @r = `dest.pl`; という方法もあるとは思うんですが、なんとか eval でやりたいのです。 なんかパイプとか繋ぎなおせば何とかなりそうな気もするんですが……。 何かご存知の方がいらっしゃいましたら、よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
子プロセスでevalし、その出力をpipeで読んではどうでしょうか。 if (open IN, "dest.pl") { local $/; $s = <IN>; close IN; } pipe RDP, WRP; if (my $pid = fork) { # 親 close WRP; chomp(@r = <RDP>); close RDP; wait; } elsif (defined $pid) { # 子 close RDP; select WRP; # 標準出力を WRP に変更 $| = 1; # バッファリングを止める eval($s); close WRP; exit; } else { die $! } # fork失敗 foreach (@r) { print "$_\n"; }
その他の回答 (1)
open(IN, "dest.pl |"); foreach(<IN>){ # 標準出力を受け取るだけの処理 # 標準出力は $_ で取れる # dest.plの内容によっては、この処理はなくてもいいでしょう } close(IN); dest.plを実行し、標準出力をパイプで取得するというのではいけないのでしょうか? evalを実行するところまでの処理が無駄だと思いますが。 .plがperlに関連付けられてないと実行されないので、openのところでは、 open(IN, "perl dest.pl |"); と明示的にperlを呼ぶ必要があるかもしれません。
補足
>dest.plを実行し、標準出力をパイプで取得するというのではいけないのでしょうか? はい。駄目なんです(^_^; 作っていただいたソースはありがたいのですが、実際には dest.pl の中身は、Perl 以外の他の言語のプログラムが雑多に混じっており、Perl 部だけを抜き出して実行する必要があるのです。 抜き出した Perl を一度テンポラリファイルに書き込む方法も考えたんですが、処理が遅くなるので eval でやりたいわけです。 まぁ、今んとこ一度ファイルに書き込む動作は必要かなという気はしてますが。
お礼
ありがとうございます。 こういうの知りたかったんです! 試してみますね!