cronでメールを送るシェルスクリプトが動かなかった件。 [Linux]
crontabで設定して、tail -f /var/log/cron を見ていて実行されていても、実際には動かないシェルスクリプトとかありますか? 自分は休日を入れて4日間もハマりましたw。
「cron シェルスクリプト 実行されない」
とかでググってみると
https://i-think-it.net/linux-cron-not-be-execute/
・cronの記載方法に間違いないか
・cronサービスは起動しているか
・スクリプトに実行権は付与されているか
・シェルスクリプトのパス指定に間違いないか
・SSH接続が可能か
・expectコマンド入りのスクリプト
があってどれも当てはまらない。きちんとコマンドラインではシェルスクリプトは実行されていて、処理のメールがきちんと届く。でもcronでは動かない。
結局、どこでコケているのか分からないので、下記のようにログに出力を出してみることにしました。
https://qiita.com/ekusuy/items/2d87f5542e2287028634
10 * * * * /home/myuser/mailsend.sh >> /tmp/cron.log 2>&1
10分が近かったのでcrontabに指定してみるとcronのログには同様に動いていたのが見えたが、やはり実行されない。/tmp/cron.logを見るとがっつりエラーが出ていました。やっとエラーの理由がわかりました。
sendmailコマンドでメールを出していたんだけど、そのsendmailコマンドが見つからないときた。
なぜか? シェルスクリプトを手動で動かしていた時は、シェルが呼び出す実行ファイルまでのパスが通っていて、恐らくcronの時はその実行パスが分からない状態になっていたようです。
確かにcronでbashを動かしていても、環境変数はどこから取ってきていいのか分からないし、cronで使われるユーザーの.bashrcなどの設定ファイルを読み込んでくれるほどのサービスはしてくれないという事ですね。なので、シェルスクリプト内の実行ファイルはフルパスにしないといけないみたい。
なので、which sendmailで調べて
/usr/sbin/sendmail
に変えて動かしたら問題がなくなりました。他のファイルのパスはどこで実行してもいいようにフルパスにしていたんだけど、コマンドまでしなくてはいけないとは気づきませんでした。コマンドラインからはカッチリ動くだけに厄介な感じです。
あとがきですが、
それまでは、
command > /dev/null 2>&1
って後ろにつけないといけないのかもなと、おまじないをしようとしていたんですが、それは余計に悪いことだったりしました。
https://qiita.com/ritukiii/items/b3d91e97b71ecd41d4ea
http://dqn.sakusakutto.jp/2012/06/shell_dev_null_2_1_crontab.html
動かないうちは少なくとも/dev/nullに捨てない方がいいですよね。
さらに後書き。
cronで実行中、エラーが出たりすると勝手にメールを出したりする。余計なお世話なんだけど、エラーが前提のシェルスクリプトだと困る。
そのための > /dev/null 2>&1 なんだろうけど、自分の場合、cron内でこれをつけてもメールが発信された。crontabの時に行頭にMAILTO=""をすると送られないとの情報もダメだった。結局エラーメールは出てしまっていたのですよね。
根本的にシェルスクリプトからエラーが出ないようにすればいいと思い、エラーが出ている三段ぐらいパイプしているところの最後に > /dev/null 2>&1 をしたら結果も闇に消し去られてしまった。エラーだけを消すには 2>/dev/null をパイプで繋げている途中でも入れないといけないみたい。結局エラー処理がそのコマンド単体で出ているから、パイプをいくつも通した後でまるっとエラー処理みたいなことはできないみたい。だからコマンド単体でエラーを殺しておく必要がある。
そんなわけでcrontabで >/dev/null 2>&1 をしようが、MAILTO=""をしようが、元のシャルスクリプトのコマンドでエラーが出てしまうと、エラーメールが容赦なく出てしまうという話でした。どうでもいいが、自分の使う環境って例外なのか、ググって出てくる情報がエアプなのかはわからないけど、実際やってみるとダメな場合が多いんだよな。んで、結局自分で解決するんだけど、他の人も本当にそれで解決しているのかなと思いました。
できなかった事を書いてある所にリンクを張ろうとしたけど、そうすると余計誘引することになるのでやめた。まぁそれでできるようになる環境ならいいけど、できないものはできないから。というか、環境が違うからか、情報が古いからなのか、どう考えてもエアプだろうという情報がかなり多いのだけれど、すぐに解決できないのはイライラするものです。まぁ嘘を書いているわけじゃないんだろうけど、当てはまらないと一体なんなん?って思うよね。
「cron シェルスクリプト 実行されない」
とかでググってみると
https://i-think-it.net/linux-cron-not-be-execute/
・cronの記載方法に間違いないか
・cronサービスは起動しているか
・スクリプトに実行権は付与されているか
・シェルスクリプトのパス指定に間違いないか
・SSH接続が可能か
・expectコマンド入りのスクリプト
があってどれも当てはまらない。きちんとコマンドラインではシェルスクリプトは実行されていて、処理のメールがきちんと届く。でもcronでは動かない。
結局、どこでコケているのか分からないので、下記のようにログに出力を出してみることにしました。
https://qiita.com/ekusuy/items/2d87f5542e2287028634
10 * * * * /home/myuser/mailsend.sh >> /tmp/cron.log 2>&1
10分が近かったのでcrontabに指定してみるとcronのログには同様に動いていたのが見えたが、やはり実行されない。/tmp/cron.logを見るとがっつりエラーが出ていました。やっとエラーの理由がわかりました。
sendmail: コマンドが見つかりません
sendmailコマンドでメールを出していたんだけど、そのsendmailコマンドが見つからないときた。
なぜか? シェルスクリプトを手動で動かしていた時は、シェルが呼び出す実行ファイルまでのパスが通っていて、恐らくcronの時はその実行パスが分からない状態になっていたようです。
確かにcronでbashを動かしていても、環境変数はどこから取ってきていいのか分からないし、cronで使われるユーザーの.bashrcなどの設定ファイルを読み込んでくれるほどのサービスはしてくれないという事ですね。なので、シェルスクリプト内の実行ファイルはフルパスにしないといけないみたい。
なので、which sendmailで調べて
/usr/sbin/sendmail
に変えて動かしたら問題がなくなりました。他のファイルのパスはどこで実行してもいいようにフルパスにしていたんだけど、コマンドまでしなくてはいけないとは気づきませんでした。コマンドラインからはカッチリ動くだけに厄介な感じです。
あとがきですが、
それまでは、
command > /dev/null 2>&1
って後ろにつけないといけないのかもなと、おまじないをしようとしていたんですが、それは余計に悪いことだったりしました。
https://qiita.com/ritukiii/items/b3d91e97b71ecd41d4ea
http://dqn.sakusakutto.jp/2012/06/shell_dev_null_2_1_crontab.html
動かないうちは少なくとも/dev/nullに捨てない方がいいですよね。
さらに後書き。
cronで実行中、エラーが出たりすると勝手にメールを出したりする。余計なお世話なんだけど、エラーが前提のシェルスクリプトだと困る。
そのための > /dev/null 2>&1 なんだろうけど、自分の場合、cron内でこれをつけてもメールが発信された。crontabの時に行頭にMAILTO=""をすると送られないとの情報もダメだった。結局エラーメールは出てしまっていたのですよね。
根本的にシェルスクリプトからエラーが出ないようにすればいいと思い、エラーが出ている三段ぐらいパイプしているところの最後に > /dev/null 2>&1 をしたら結果も闇に消し去られてしまった。エラーだけを消すには 2>/dev/null をパイプで繋げている途中でも入れないといけないみたい。結局エラー処理がそのコマンド単体で出ているから、パイプをいくつも通した後でまるっとエラー処理みたいなことはできないみたい。だからコマンド単体でエラーを殺しておく必要がある。
そんなわけでcrontabで >/dev/null 2>&1 をしようが、MAILTO=""をしようが、元のシャルスクリプトのコマンドでエラーが出てしまうと、エラーメールが容赦なく出てしまうという話でした。どうでもいいが、自分の使う環境って例外なのか、ググって出てくる情報がエアプなのかはわからないけど、実際やってみるとダメな場合が多いんだよな。んで、結局自分で解決するんだけど、他の人も本当にそれで解決しているのかなと思いました。
できなかった事を書いてある所にリンクを張ろうとしたけど、そうすると余計誘引することになるのでやめた。まぁそれでできるようになる環境ならいいけど、できないものはできないから。というか、環境が違うからか、情報が古いからなのか、どう考えてもエアプだろうという情報がかなり多いのだけれど、すぐに解決できないのはイライラするものです。まぁ嘘を書いているわけじゃないんだろうけど、当てはまらないと一体なんなん?って思うよね。
2022-01-27 09:11
コメント(0)
コメント 0