phpで外部コマンド実行(shell_exec)が上手くいかなかった時のメモ
2012年02月27日 13時54分
社内サーバでmailqを管理する簡易的なWebアプリを作っててはまったのでメモ。
目的
メールの即時配信をやめ、キューに溜めてWeb経由で閲覧・配信・削除をできるようにする。
CentOS / postfix
手順
- 1)postfixの設定(/etc/postfix/main.cf)に以下を追加してsmtpでの配信を即時配信ではなくメールキューに溜めるように設定。
-
1defer_transports = smtp
- 2)phpでmailqueueの設定一覧を取得
-
1$queue_list = shell_exec(escapeshellcmd(""/usr/sbin/postqueue -p""))
こちらはなんの問題もなく動いた - 3)phpでmailqueueにあるメールを削除
-
1$del_msg = shell_exec(escapeshellcmd("postsuper -d [キューID]"))
こちらはさっぱり動かない。
戻り値も空なのでどうしたものか、、、とりあえず関数をsystemやpassthruに変えてみたけど変化なし。
標準エラー出力が取れていないのではと思い調べてみると後ろに”2>&1″を付けることで標準エラー出力も標準出力に吐き出せるので試してみる。
1$del_msg = shell_exec(escapeshellcmd("postsuper -d [キューID] 2>&1"))これでもメッセージは何もでない。
コマンド自体間違っていないか実行したコマンドをechoしてターミナルから実行してみると正常に動作して消せる。となると権限周りが怪しくなるのでsudoしてみることに。
1$del_msg = shell_exec(escapeshellcmd("sudo postsuper -d [キューID] 2>&1"))とやっても何も動かない。
自分しか使っていないローカルマシンなのでセキュリティなど無視して以下に設定してみても駄目。1234$: visudo#ADDapache ALL=(ALL) NOPASSWD: ALLしかし上記を追加してからエラーメッセージが表示されるようになった。
以下のようなもの。1sorry, you must have a tty to run sudoこれでググってみるとvisudoで以下の行をコメントアウトすることにより解決するようだった。
12345$:vi /etc/sudoersDefaults requiretty↓#Defaults requiretty上で見事に解決。
無事にコマンドが実行されメールキューのメールが削除できました。※自PC内のVMだからやりたい放題やっていますが外部サーバ等の場合はこの記事の内容はセキュリティ上問題が多いのでおすすめしません。