[PHP]exec()直後にApacheを(reload|graceful|restart)したら不思議な結果になった
実験コード
まず外部コマンドを用意します。sleep.sh
#!/bin/sh
for i in $(seq 1 20) ; do date ; sleep 1;
次に、それをexec()で呼び出すPHPコードを書きました。フォアグラウンド実行、バックグラウンド実行、バックグラウンド+nohup実行の3通り試しました。
フォアグラウンド実行
<?php
exec("./sleep.sh > log.txt");
バックグラウンド実行
<?php
exec("./sleep.sh > log.txt &");
バックグラウンド+nohup実行
<?php
exec("nohup ./sleep.sh > log.txt &");
ブラウザから上記PHPスクリプトを実行して、直後にApacheの再起動をかけて、sleep.shのプロセスがどうなるかを観察しました。Apache再起動は次の3つを試しました。
/etc/init.d/httpd restart
/etc/init.d/httpd reload
/etc/init.d/httpd graceful
実験結果
このようになりました。○...外部コマンドが起動しつづけた
×...外部コマンドが停止した
フォアグラウンド | バックグラウンド | nohup + バックグラウンド | |
---|---|---|---|
restart | × | × | × |
reload | × | × | 〇 |
graceful | 〇 | 〇 | 〇 |
結果の解釈について
/etc/init.d/httpd restart は中身が stop & start なので、どのケースでも停止するのはうなづけます。
etc/init.d/httpd reload は中身が kill -HUPなので、nohupをつけない限りは停止するのもわかります。
よくわからないのがバックグラウンドかつgracefulのケースです。
バックグランドexecした後、httpdプロセスは次のリクエストを待っているはずなので、gracefulで即再起動されて外部コマンドが停止するかと思ったのですが、予想に反して停止しませんでした。
どなたか、このメカニズムがわかる人がいたら教えてください。