- foo.php -
<?php
exec("ls -la");
?>
これをコマンドラインから php -f foo.php と叩いたところ、
sh: /ls: No such file or directory
というエラーになります。PHP 4.3.9 (cgi)です。
何が原因でしょうか?
エラーメッセージを見ると、shがルートにlsを探しに行っているようですが、
恐らくUnixコマンドを実行して、実行結果を格納するという流れだと思いますが、
execはあくまで「プログラムを実行する」関数ですので、Unixコマンドを直接実行できません。
別ソースのプログラムを起動する際に使います。
PHPからUnixコマンドを直接呼び出す場合は「shell_exec」を使います。
http://php.s3.to/man/function.shell-exec.html
http://manual.xwd.jp/function.shell-exec.html
今回の場合、下記のような感じですね。
$str = shell_exec('ls -la');
echo "$str";
尚、Unixコマンドの実行を許可するという事は「OSインジェクション」という脆弱性にも繋がるので、
セキュリティの対策は十分に気をつけて下さい。作り方によっては最悪、rootを奪取されてしまいます。
ありがとうございます。
実は本当に実行したいのはImageMagickのコマンドでして、それがうまくいかず
試しにサンプルのような簡単なものを書いて実行してみても同じ結果だったので
原因は同じところにあるのかなと思っていました。
lsコマンドにPATHが通ってないだけかと思います。
以下のようにフルパスで指定してみてはどうでしょうか。
exec("/bin/ls -la")
ありがとうございます。
フルパスを指定しても結果は同じでした。
safe_mode が ON の状態はセーフモードと呼ばれており、「セーフモードにより制限を受けるか無効となる関数」に明記されており通り、exec 関数は
safe_mode_exec_dir の中でのみ実行可能です。現実的な理由により、現在、実行パスに ..を含めることは許可されていません。
ということになります。
ところが、ls はシェル内コマンドですので、うまく指定してやることができません。
根本的な解決策としては、safe_mode を OFF にすることです。
セキュリティ上の関係などで OFF にできない場合は、safe_mode_exec_dir に ImageMagick のパスを通してやれば、とりあえず ImageMagick だけでも動くようになるはずです。
もし動かないようでしたら原因は別にあると思うので、結果をお知らせください。
※設定された回答回数の上限になりました。さらにフォローが必要でしたら、コメント欄を開けていただくか、回答回数を増やしてください。
ありがとうございます。
結局、php.iniのsafe_mode_exec_dirにImageMagickの存在するパスを設定してあげただけで解決しました。
ありがとうございました。
safe_mode は ON になっており、かつ、safe_mode_exec_dir は空白になっているようです。
コマンドラインPHPはCGI版だと思われます。