プロが教えるわが家の防犯対策術!

 凄い不思議な質問タイトルになってしまいましたが……(笑)

 下記のようなソースを実行したとします。

-------------------------○ 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 でやりたいのです。

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

A 回答 (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";
}
    • good
    • 0
この回答へのお礼

 ありがとうございます。

 こういうの知りたかったんです!
 試してみますね!

お礼日時:2004/06/29 17:24

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 でやりたいわけです。

 まぁ、今んとこ一度ファイルに書き込む動作は必要かなという気はしてますが。

補足日時:2004/06/29 14:45
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!