- ベストアンサー
phpのshell_exec関数の動作に関する質問
- phpのshell_exec関数を使用してtest.cgiを実行すると、コマンドライン後の$filebの変化がない
- ブラウザから実行するとtest.phpは正常に実行されているが、コマンドライン実行後の$filebの変化がない
- test.cgiではperlライブラリを使用しており、phpには同等のライブラリがないため、shell_exec関数で実行している
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
ポイントは4つ (1)shell_execが実行できない shell_execでlsなどを実行してみて動くことを確認してみてください (2)shell_execが実行できているが、実行できないと勘違いしている 可能性がないとはいえないので、複数のテストをしてみてください (3)パスが間違いっている shell_execの実行の際には原則ルートからのフルパスです。 なんらかの勘違いで、カレントからの相対パスにしてしまっているなどの ボーンヘッドもないとはいえません (4)実行権限 基本的にはapacheの実行者が普通のコマンドを実行できることは稀です sudoなどと絡めてやるのが妥当だとおもいます。 いずれにしろ、ログを吐き出したり、戻り値を工夫したりしてとにかく エラーを吐き出させてデバッグするしかないと思いますよ。
その他の回答 (2)
- superside0
- ベストアンサー率64% (461/714)
よくあるパターンは、 ・アカウントA でログインして、コマンド実行で 新規にfilebを生成した (この場合、実行プロセスのオーナーはAなので、filebのオーナーは Aとなる) ・PHP内から同じコマンド実行をするようにしておいて、ブラウザからアクセスした (この場合、実行プロセスのオーナーは通常apacheなので、apacheの権限でファイルを上書きしにいくが、既存ファイルとオーナーが違うので上書きできない) この場合は、filebに、apacheからでも上書きができきるように otherからの書き込み権限の設定が必要となります。 (chmod 646 fileb 等) CGIカウンター用のファイルなど、固定のファイル名ならこれでもいいですが もし、PHPから、新規にファイルを作ることもあるなら、ファイルを置くフォルダに、 アカウントapacheで新規ファイルが作れる権限が必要です。 (chmod 757 フォルダ 等) なお、生成されたファイルの後処理関係など、運用との絡みでや サーバーのセキュリティーポリシーとの絡みで、 sudoでコマンドの実行プロセスのオーナー自身を変えたほうがよい場合もあると思います。
お礼
ありがとうございます。 引き続きテストをしていたところ解決できましたのでお知らせいたします。 最初の情報提供の範囲外での結論となりましたことをお詫びいたします。 そして誤ってお伝えしてしまったことの訂正、 お伝えできなかったことも合わせてお知らせいたします。 オリジナルのtest.cgiのperlライブラリに関する行は use MP3::Tag; のみであり、 use lib qw(/path/lib); という行は最初は存在していませんでした。 従ってライブラリ読み込みの有無によって動作するしないとお知らせした部分は、 use MP3::Tag; という行のみに対してのことです。 テストを進める中で use lib qw(/path/lib); という行が必要ではないかということに気づき (つまりコマンドラインではライブラリパスがわかるけれども、 ブラウザから実行された場合にはライブラリパスがわからないのでは?と考えつきました) しかしライブラリパスを追加してもすぐには動きませんでした。 さらにテストを実施していたところ、 正しいライブラリパスが use lib qw(/realpath/lib); であることに気づき動作が確認できました。 皆様のご協力に感謝いたします。 ありがとうございました。
補足
ご回答ありがとうございます。 現在の調査結果をお知らせいたしますので、 可能であれば引き続きのサポートをお願いいたします。 補足は一番最初のご回答者にまとめさせていただきます。
- notnot
- ベストアンサー率47% (4900/10359)
phpスクリプトの実行はどうやっているのか?シェルコマンドラインから?ウェブサーバ経由で? 後者なら、実行権限の問題でしょうね。apacheが$filebに更新権限が無いとか。
お礼
ありがとうございます。 引き続きテストをしていたところ解決できましたのでお知らせいたします。 最初の情報提供の範囲外での結論となりましたことをお詫びいたします。 そして誤ってお伝えしてしまったことの訂正、 お伝えできなかったことも合わせてお知らせいたします。 オリジナルのtest.cgiのperlライブラリに関する行は use MP3::Tag; のみであり、 use lib qw(/path/lib); という行は最初は存在していませんでした。 従ってライブラリ読み込みの有無によって動作するしないとお知らせした部分は、 use MP3::Tag; という行のみに対してのことです。 テストを進める中で use lib qw(/path/lib); という行が必要ではないかということに気づき (つまりコマンドラインではライブラリパスがわかるけれども、 ブラウザから実行された場合にはライブラリパスがわからないのでは?と考えつきました) しかしライブラリパスを追加してもすぐには動きませんでした。 さらにテストを実施していたところ、 正しいライブラリパスが use lib qw(/realpath/lib); であることに気づき動作が確認できました。 皆様のご協力に感謝いたします。 ありがとうございました。
補足
皆様ご回答ありがとうございます。 現在の調査結果をお知らせいたしますので、 可能であれば引き続きのサポートをお願いいたします。 この補足は一番最初のご回答者にまとめさせていただきます。 まず、問題の原因を探るためにtest.php, test.cgiを簡略化してみました。 そして皆様からご指摘のあった、権限、shell_execの動作、パスについては問題ないことを確認しました。 ちなみにこのWEBサーバーのhttpdは一般ユーザー権限で動作しており、かつ、 phpはapacheのモジュールとして動作しています。 既存のphpスクリプトは600、perlスクリプトは700で全て動作しています。 (環境の追加情報:perl v5.8.9) 簡略化したtest.phpの内容 ------------------------------------------ <?php // test.php shell_exec("/path/test.cgi"); ?> ------------------------------------------ 簡略化したtest.cgiの内容 ------------------------------------------ #! /usr/bin/perl -w # test.cgi my $txt = '/path/test.txt'; open(OUT, ">> $txt"); print OUT "access from browser\n"; close(OUT); ------------------------------------------ まずブラウザによって上記のtest.php, test.cgiの連携動作は確認できました。 この後、オリジナルのtest.cgiに含まれている行を、 様々な組み合わせで追加してブラウザからの実行を試みたところ、 連携動作する場合としない場合があることがわかりました。 オリジナルのtest.cgiには、 ------------------------------------------ use lib qw(/path/lib); use MP3::Tag; ------------------------------------------ とライブラリのパスを指定して読み込んでいる行があります。 このライブラリに関する行が含まれている場合は連携動作せず、 含まれていない場合は連携動作することがわかりました。 そこで追加質問です。 2 phpのshell_exec関数から呼び出されたperlスクリプトが、 ライブラリを読み込んだときに連携動作しなくなる理由としてどのようなことが考えられるでしょうか?
お礼
ありがとうございます。 引き続きテストをしていたところ解決できましたのでお知らせいたします。 最初の情報提供の範囲外での結論となりましたことをお詫びいたします。 そして誤ってお伝えしてしまったことの訂正、 お伝えできなかったことも合わせてお知らせいたします。 オリジナルのtest.cgiのperlライブラリに関する行は use MP3::Tag; のみであり、 use lib qw(/path/lib); という行は最初は存在していませんでした。 従ってライブラリ読み込みの有無によって動作するしないとお知らせした部分は、 use MP3::Tag; という行のみに対してのことです。 テストを進める中で use lib qw(/path/lib); という行が必要ではないかということに気づき (つまりコマンドラインではライブラリパスがわかるけれども、 ブラウザから実行された場合にはライブラリパスがわからないのでは?と考えつきました) しかしライブラリパスを追加してもすぐには動きませんでした。 さらにテストを実施していたところ、 正しいライブラリパスが use lib qw(/realpath/lib); であることに気づき動作が確認できました。 皆様のご協力に感謝いたします。 ありがとうございました。
補足
ご回答ありがとうございます。 現在の調査結果をお知らせいたしますので、 可能であれば引き続きのサポートをお願いいたします。 補足は一番最初のご回答者にまとめさせていただきます。