
popen() を使いこなせるようになろうとしているのですが、少し難しくてつまづいています。この関数は基本的に、指定したスクリプトをバックグラウンドで実行させるためのもの、と考えてよろしいでしょうか?
マニュアルを読んでわからなかった言葉があります。「パイプ」「片方向ストリーム」 なのですが、検索して、パイプはなんとなく出入力先のポートだということが書いてあったのですが、いまいちピンときません。パイプを経由することで生まれるメリットのようなものはあるのでしょうか?
次に、ファイルポインタなのですが、スクリプトを実行させるのになぜこれが必要になるのでしょうか?おそらくほとんどのスクリプトがファイルの先頭にポインタを置く必要があると思うのですが、例えば'a'などとして、最後に置くとスクリプトが実行されなくなったりしませんでしょうか?
現在の理解度では
popen("php -f $script", "r");
exec("php -f $script > /dev/null &");
の違いがわかりません。どちらも$sriptをバックグラウンドで実行してくれますが、マニュアルに記載されているファイルポインタの指定とパイプのオープンがもたらす決定的な違いなどどのようなものになるのでしょうか?
また、popen()使用後に、pclose() で閉じないでいるとどのようなことが起こるのでしょうか?
たくさんありますが、ひとつでもお分かりになるかたおられましたらどうぞよろしくお願いいたします。
No.1ベストアンサー
- 回答日時:
この辺は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() ではそのような心配はしなくてよいのでしょうか?ほったらかしにしてしまったプロセスを終了させる方法などありますでしょうか?
No.2
- 回答日時:
すみません。
他の言語とごっちゃになってました。execも第二引数を使えば起動したプロセスの出力を取れますね。
ただ、popenの場合一行分もしくは指定バイト数読み取れば
いったん戻ってきますが、execの場合は起動したプロセスが終了するまで
制御が戻ってこないと思われます。
pcloseで始末しなかったときの起動プロセスの後始末ですが、
プロセスIDがわかればシグナル送って強制終了とかできると思いますが
(PHPの組み込み関数でその手のものがあるかどうかは知りません)、
ゾンビプロセスとなってとどまり続けてしまうのではないでしょうか?
PHPのマニュアルを再確認してみましたが、外部プログラムを起動する関数が
exec
passthru
popen
proc_open
shell_exec
system
とたくさんありそれぞれ微妙に違うのでややこしいこと極まりないですね。
結局popen() とexec() の違いがわからずじまいになってしまったのですが、それはそれでいつか理解できる時まで保留させようと思います。ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
タスクマネージャーのプロセス...
-
指定した実行中プロセスの、指...
-
Process.Startの戻り値を後で取得
-
Shellでの環境変数
-
GPLによるソース公開の回避方法
-
バックグラウンドのプロセスの...
-
【C#】別プロセスがロックか...
-
DLLにおいて、最後のプロセスデ...
-
共有メモリを使う場合のCPU負荷...
-
iPodの取り外しの際のエラーメ...
-
execvpでのcdコマンドについて。
-
Macターミナルで実行中のプログ...
-
家電製品の電力周波数を変える機械
-
TCP/IP通信時のサーバーからの受信
-
このレジの並び方は間違ってま...
-
InternetOpenUrlの引数URL文字...
-
実行時のコマンドプロンプトを...
-
ボタンが押された事を検知する...
-
h8マイコンで AD変換ができ...
-
割り込みの衝突
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
プロセスのアタッチ・デタッチ...
-
非表示になったエクセルは?
-
C#でのbatファイル実行結果取得
-
Process.Startの戻り値を後で取得
-
タスクマネージャーのプロセス...
-
SendMessageが失敗するときがある
-
VB6.0 SHELLで起動...
-
Linuxでのスレッド間メッセージ...
-
vb.netでEXCEL起動がうまくでき...
-
explorer.exeが異様にメモリを食う
-
プロセスIDの取得方法について
-
IISがフリーズ
-
jdbcのプロセスの処理について
-
c言語でプロセスIDを調べたい
-
セマフォとmutexの違いは?
-
警告『 別のプロセスで使用され...
-
ADOでアクセスのレコードに...
-
OSPFでプロセスを分ける意義に...
-
Windowsでのfork方法
おすすめ情報