せっかく作ったTwitter botだが、なぜかcronだと動かなかった。そこでどうにか直してみる。
というわけでメモる
cron : UNIXなどにおいてジョブ(コマンド)を決まった時間に実行させることのできる。
というわけでメモる
今回問題になっていたのが「絶対パス」と「相対パス」の違いと「cronの実行ディレクトリ」だった。
「絶対パス」は一番上の階層から指定する方法でたとえば「/etc/cron.daily/makewhatis.cron」とかそんな感じの物。深い階層(ディレクトリ数が多い)ときには非常に長ったらしくなったり、他のPCにコピペして階層構造が違ったりすると「ファイルがない!」と言い出す。
「相対パス」は今いるディレクトリからの位置を指定する方法で例えば「今いるディレクトリからみて1つ上のディレクトリにあるimgディレクトリ」だと「../img」とかになる。ディレクトリごとコピーすれば他のPCでも使えるんだけど、「今いるディレクトリ」に注意する必要が出てくる。
作成したbotは必要なファイルとかをすべて相対パスで指定してあったので罠にはまったと。。。
「絶対パス」は一番上の階層から指定する方法でたとえば「/etc/cron.daily/makewhatis.cron」とかそんな感じの物。深い階層(ディレクトリ数が多い)ときには非常に長ったらしくなったり、他のPCにコピペして階層構造が違ったりすると「ファイルがない!」と言い出す。
「相対パス」は今いるディレクトリからの位置を指定する方法で例えば「今いるディレクトリからみて1つ上のディレクトリにあるimgディレクトリ」だと「../img」とかになる。ディレクトリごとコピーすれば他のPCでも使えるんだけど、「今いるディレクトリ」に注意する必要が出てくる。
作成したbotは必要なファイルとかをすべて相対パスで指定してあったので罠にはまったと。。。
今回はこれをミスってなかなか思い通りに動かなかった。
「crontab -e」で定期実行の設定をすると、crontabコマンドを実行したユーザのホームディレクトリに移動してジョブを実行しようとするらしい。
cronの設定例
というわけで「BotMain.rb」をcronを使って15分おきに実行したいときの例。
事前に「BotMain.rb」がエラーなく動く事を確かめます。cronで実行するとエラーログとかがどっかのログファイルに出力されてしまうので、cronを使いつつデバッグは非常に面倒です。
次に実行用のスクリプト(1RunBot.sh)を用意します。
#スクリプトのあるディレクトリのパスを調べる
##このスクリプトの絶対パス
fullpath=$0
##このスクリプトのファイル名
filename=`basename $0`
##このスクリプトのあるディレクトリのパス
location=`echo $fullpath | sed "s/$filename//"`
#スクリプトのあるディレクトリに移動
cd `echo $location`
#同じディレクトリにある「BotMain.rb」を実行
##標準エラー出力は「2ErrorLog.txt」に出力
##標準出力は「3RunLog.txt」に出力
/usr/bin/ruby BotMain.rb 2>> 2ErrorLog.txt 1>> 3RunLog.txt
一応、他のディレクトリに移動して、他のディレクトリから実行してもきちんと動くかテストします。
cd ../
sh 1RunBot.shのパス
きちんと動いてる事を確認したらcrontabコマンドでcronに登録します。crontabの設定画面はviなので、あらかじめviの使い方をおぼえておきませう。
crontab -e
viが起動するので以下のような形式でジョブを登録
分 時 日 月 曜 コマンド
今回は「15分おきに1RunBot.shを実行」としたいので
*/15 * * * * /aaa/bbb/ccc/ddd/1RunBot.sh
相対パスしていでも良かったりしますが、あとで頭がこんがらがるので今回は絶対パスにしておきます。
あとは15分ごとにきちんと動いてるのをTwitterにログインして確認。一応cronのログファイルは「/var/log/cron」だということは書いておく。
PR