アプリ版:「スタンプのみでお礼する」機能のリリースについて

phpのshell_exec関数の動作に関する質問です。
環境はFreeBSD7.1 php5.2.13です。

もともとperlスクリプトtest.cgiがあって、
/path/test.cgi filea fileb (以後これをコマンドラインという)
というコマンドラインが正常に実行されることが確認済みです。
このコマンドラインが実行されるとfilebの内容が変化します。

次にphpスクリプトからコマンドラインを実行するために
test.phpスクリプトの途中に、
shell_exec("/path/test.cgi $filea $fileb");
と書きました。
(test.cgiではperlライブラリを読み込んでいます。
phpには同等のライブラリがないためにやむを得ずこうしています。)

ところがtest.phpを(ブラウザから)実行しても
コマンドライン実行後に期待される$filebの変化がありません。
つまりコマンドラインが実行された形跡がないのです。

test.phpスクリプトの$filea, $filebが正しく変数展開されていることは確認済みです。
FireFoxブラウザから見るとtest.phpスクリプトは特にエラーもなく正常に実行されているように見えます。

質問
1 正常に実行できるコマンドラインをphpのshell_exec関数で実行できない理由としてどのようなことが考えられるでしょうか。

A 回答 (3件)

ポイントは4つ



(1)shell_execが実行できない
shell_execでlsなどを実行してみて動くことを確認してみてください

(2)shell_execが実行できているが、実行できないと勘違いしている
可能性がないとはいえないので、複数のテストをしてみてください

(3)パスが間違いっている
shell_execの実行の際には原則ルートからのフルパスです。
なんらかの勘違いで、カレントからの相対パスにしてしまっているなどの
ボーンヘッドもないとはいえません

(4)実行権限
基本的にはapacheの実行者が普通のコマンドを実行できることは稀です
sudoなどと絡めてやるのが妥当だとおもいます。

いずれにしろ、ログを吐き出したり、戻り値を工夫したりしてとにかく
エラーを吐き出させてデバッグするしかないと思いますよ。

この回答への補足

ご回答ありがとうございます。
現在の調査結果をお知らせいたしますので、
可能であれば引き続きのサポートをお願いいたします。
補足は一番最初のご回答者にまとめさせていただきます。

補足日時:2010/07/24 01:45
    • good
    • 0
この回答へのお礼

ありがとうございます。
引き続きテストをしていたところ解決できましたのでお知らせいたします。
最初の情報提供の範囲外での結論となりましたことをお詫びいたします。
そして誤ってお伝えしてしまったことの訂正、
お伝えできなかったことも合わせてお知らせいたします。

オリジナルのtest.cgiのperlライブラリに関する行は
use MP3::Tag;
のみであり、
use lib qw(/path/lib);
という行は最初は存在していませんでした。

従ってライブラリ読み込みの有無によって動作するしないとお知らせした部分は、
use MP3::Tag;
という行のみに対してのことです。

テストを進める中で
use lib qw(/path/lib);
という行が必要ではないかということに気づき
(つまりコマンドラインではライブラリパスがわかるけれども、
ブラウザから実行された場合にはライブラリパスがわからないのでは?と考えつきました)

しかしライブラリパスを追加してもすぐには動きませんでした。
さらにテストを実施していたところ、
正しいライブラリパスが
use lib qw(/realpath/lib);
であることに気づき動作が確認できました。

皆様のご協力に感謝いたします。
ありがとうございました。

お礼日時:2010/07/24 03:23

よくあるパターンは、


・アカウントA でログインして、コマンド実行で 新規にfilebを生成した
(この場合、実行プロセスのオーナーはAなので、filebのオーナーは Aとなる)

・PHP内から同じコマンド実行をするようにしておいて、ブラウザからアクセスした
(この場合、実行プロセスのオーナーは通常apacheなので、apacheの権限でファイルを上書きしにいくが、既存ファイルとオーナーが違うので上書きできない)


この場合は、filebに、apacheからでも上書きができきるように
otherからの書き込み権限の設定が必要となります。
(chmod 646 fileb 等)


CGIカウンター用のファイルなど、固定のファイル名ならこれでもいいですが
もし、PHPから、新規にファイルを作ることもあるなら、ファイルを置くフォルダに、
アカウントapacheで新規ファイルが作れる権限が必要です。
(chmod 757 フォルダ 等)


なお、生成されたファイルの後処理関係など、運用との絡みでや
サーバーのセキュリティーポリシーとの絡みで、
sudoでコマンドの実行プロセスのオーナー自身を変えたほうがよい場合もあると思います。

この回答への補足

ご回答ありがとうございます。
現在の調査結果をお知らせいたしますので、
可能であれば引き続きのサポートをお願いいたします。
補足は一番最初のご回答者にまとめさせていただきます。

補足日時:2010/07/24 01:45
    • good
    • 0
この回答へのお礼

ありがとうございます。
引き続きテストをしていたところ解決できましたのでお知らせいたします。
最初の情報提供の範囲外での結論となりましたことをお詫びいたします。
そして誤ってお伝えしてしまったことの訂正、
お伝えできなかったことも合わせてお知らせいたします。

オリジナルのtest.cgiのperlライブラリに関する行は
use MP3::Tag;
のみであり、
use lib qw(/path/lib);
という行は最初は存在していませんでした。

従ってライブラリ読み込みの有無によって動作するしないとお知らせした部分は、
use MP3::Tag;
という行のみに対してのことです。

テストを進める中で
use lib qw(/path/lib);
という行が必要ではないかということに気づき
(つまりコマンドラインではライブラリパスがわかるけれども、
ブラウザから実行された場合にはライブラリパスがわからないのでは?と考えつきました)

しかしライブラリパスを追加してもすぐには動きませんでした。
さらにテストを実施していたところ、
正しいライブラリパスが
use lib qw(/realpath/lib);
であることに気づき動作が確認できました。

皆様のご協力に感謝いたします。
ありがとうございました。

お礼日時:2010/07/24 03:22

phpスクリプトの実行はどうやっているのか?シェルコマンドラインから?ウェブサーバ経由で?



後者なら、実行権限の問題でしょうね。apacheが$filebに更新権限が無いとか。

この回答への補足

皆様ご回答ありがとうございます。
現在の調査結果をお知らせいたしますので、
可能であれば引き続きのサポートをお願いいたします。
この補足は一番最初のご回答者にまとめさせていただきます。

まず、問題の原因を探るために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スクリプトが、
  ライブラリを読み込んだときに連携動作しなくなる理由としてどのようなことが考えられるでしょうか?

補足日時:2010/07/24 01:44
    • good
    • 0
この回答へのお礼

ありがとうございます。
引き続きテストをしていたところ解決できましたのでお知らせいたします。
最初の情報提供の範囲外での結論となりましたことをお詫びいたします。
そして誤ってお伝えしてしまったことの訂正、
お伝えできなかったことも合わせてお知らせいたします。

オリジナルのtest.cgiのperlライブラリに関する行は
use MP3::Tag;
のみであり、
use lib qw(/path/lib);
という行は最初は存在していませんでした。

従ってライブラリ読み込みの有無によって動作するしないとお知らせした部分は、
use MP3::Tag;
という行のみに対してのことです。

テストを進める中で
use lib qw(/path/lib);
という行が必要ではないかということに気づき
(つまりコマンドラインではライブラリパスがわかるけれども、
ブラウザから実行された場合にはライブラリパスがわからないのでは?と考えつきました)

しかしライブラリパスを追加してもすぐには動きませんでした。
さらにテストを実施していたところ、
正しいライブラリパスが
use lib qw(/realpath/lib);
であることに気づき動作が確認できました。

皆様のご協力に感謝いたします。
ありがとうございました。

お礼日時:2010/07/24 03:23

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