- 締切済み
popen について
popen() を使いこなせるようになろうとしているのですが、少し難しくてつまづいています。この関数は基本的に、指定したスクリプトをバックグラウンドで実行させるためのもの、と考えてよろしいでしょうか? マニュアルを読んでわからなかった言葉があります。「パイプ」「片方向ストリーム」 なのですが、検索して、パイプはなんとなく出入力先のポートだということが書いてあったのですが、いまいちピンときません。パイプを経由することで生まれるメリットのようなものはあるのでしょうか? 次に、ファイルポインタなのですが、スクリプトを実行させるのになぜこれが必要になるのでしょうか?おそらくほとんどのスクリプトがファイルの先頭にポインタを置く必要があると思うのですが、例えば'a'などとして、最後に置くとスクリプトが実行されなくなったりしませんでしょうか? 現在の理解度では popen("php -f $script", "r"); exec("php -f $script > /dev/null &"); の違いがわかりません。どちらも$sriptをバックグラウンドで実行してくれますが、マニュアルに記載されているファイルポインタの指定とパイプのオープンがもたらす決定的な違いなどどのようなものになるのでしょうか? また、popen()使用後に、pclose() で閉じないでいるとどのようなことが起こるのでしょうか? たくさんありますが、ひとつでもお分かりになるかたおられましたらどうぞよろしくお願いいたします。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- sakusaker7
- ベストアンサー率62% (800/1280)
すみません。他の言語とごっちゃになってました。 execも第二引数を使えば起動したプロセスの出力を取れますね。 ただ、popenの場合一行分もしくは指定バイト数読み取れば いったん戻ってきますが、execの場合は起動したプロセスが終了するまで 制御が戻ってこないと思われます。 pcloseで始末しなかったときの起動プロセスの後始末ですが、 プロセスIDがわかればシグナル送って強制終了とかできると思いますが (PHPの組み込み関数でその手のものがあるかどうかは知りません)、 ゾンビプロセスとなってとどまり続けてしまうのではないでしょうか? PHPのマニュアルを再確認してみましたが、外部プログラムを起動する関数が exec passthru popen proc_open shell_exec system とたくさんありそれぞれ微妙に違うのでややこしいこと極まりないですね。
- sakusaker7
- ベストアンサー率62% (800/1280)
この辺はUNIXでのCプログラミングの経験がないと わかりづらいかもしれませんね。 > popen("php -f $script", "r"); > exec("php -f $script > /dev/null &"); > > の違いがわかりません。 popen の嬉しいところは起動したプロセスの標準入力に データを送ったり、逆にプロセスの標準出力からデータを 受け取ることができるところにあるので、この例ではpopenを使う意味がないです。 ファイルポインタはデータのやり取りの際に使います。それとpopenの指定で "a"は使えなかったはずです。 たとえばあるディレクトリにあるファイル名を得たいとして、 $ifp = popen("/bin/ls", "r") while (!feof($handle)) { $item = fgets($ifp) echo '<li>' . $item . '</li>' } ということができます。 execでは直接にはできませんよね? > popen()使用後に、pclose() で閉じないでいるとどのようなことが起こるのでしょうか? pclose() で最期を見取ってやらないと起動したプロセスが 終われません。
お礼
>execでは直接にはできませんよね? 直接的というのはどういうことなのでしょうか? <?php exec('ls', $output); foreach($output as $line) { echo '<li>' . $line . '</li>'; } ?> 教えていただいたコードがそのままでは動きませんでしたので修正いたしました。 <? $ifp = popen("/bin/ls", "r"); while(!feof($ifp)){ $item = fgets($ifp); echo '<li>' . $item . '</li>'; } ?> この場合、pclose をしていないのですが、プロセスがそのまま残っているということでしょうか?では exec() ではそのような心配はしなくてよいのでしょうか?ほったらかしにしてしまったプロセスを終了させる方法などありますでしょうか?
お礼
結局popen() とexec() の違いがわからずじまいになってしまったのですが、それはそれでいつか理解できる時まで保留させようと思います。ありがとうございました。