• ベストアンサー

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 でやりたいのです。  なんかパイプとか繋ぎなおせば何とかなりそうな気もするんですが……。  何かご存知の方がいらっしゃいましたら、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • leaz024
  • ベストアンサー率75% (398/526)
回答No.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"; }

noname#25358
質問者

お礼

 ありがとうございます。  こういうの知りたかったんです!  試してみますね!

その他の回答 (1)

noname#227796
noname#227796
回答No.1

open(IN, "dest.pl |"); foreach(<IN>){  # 標準出力を受け取るだけの処理  # 標準出力は $_ で取れる  # dest.plの内容によっては、この処理はなくてもいいでしょう } close(IN); dest.plを実行し、標準出力をパイプで取得するというのではいけないのでしょうか? evalを実行するところまでの処理が無駄だと思いますが。 .plがperlに関連付けられてないと実行されないので、openのところでは、 open(IN, "perl dest.pl |"); と明示的にperlを呼ぶ必要があるかもしれません。

noname#25358
質問者

補足

>dest.plを実行し、標準出力をパイプで取得するというのではいけないのでしょうか?  はい。駄目なんです(^_^;  作っていただいたソースはありがたいのですが、実際には dest.pl の中身は、Perl 以外の他の言語のプログラムが雑多に混じっており、Perl 部だけを抜き出して実行する必要があるのです。  抜き出した Perl を一度テンポラリファイルに書き込む方法も考えたんですが、処理が遅くなるので eval でやりたいわけです。  まぁ、今んとこ一度ファイルに書き込む動作は必要かなという気はしてますが。

関連するQ&A

専門家に質問してみよう