動かし続ける

INPUT · スライド

決めた時刻に動かす

01 / 08

あなたが見ていないあいだ

ここまでの11章で覚えた道具は、全部打ったら動くものだったね。

~ $ ./tenken.sh

打つと動く。打たないと動かない。当たり前でしょう。

でも、こういう仕事があるんだ。

毎朝5時に、ログを片づける5分ごとに、ディスクの空きを見る毎週日曜に、まとめを作る

毎朝5時に自分で起きて打つのは、いやだよね。ここから先は「打たなくても動く」話だよ。

仕組みはとても単純だよ。

> 時刻と、やることを1行ずつ書いた表を1枚あずける

あずける相手は crond という係だよ。この係はすでに動いているんだ。

~ $ ps -o pid,args | grep crond   77 /usr/sbin/crond -f

いたでしょう! あなたが端末を開く前から、ずっと1分ごとに時計を見て「そろそろやることはないかな」と待っているんだ。

この係にあずける表を crontab と呼ぶよ。「cron の table(表)」だね。

今日やることは3つだよ。

1. 表の書き方(5つの欄)2. あずける・見る・消す(crontab)3. cron の中は別の世界(環境・出力)

章11で書いたスクリプトに時刻を与えると、はじめて仕組みになるんだ。

02 / 08

5つの欄と、やること

表の1行はこうなっているよ。

分 時 日 月 曜  やること

数字が5つ並んで、そのあとにコマンドだね。読んでみようか。

0 5 * * * /bin/echo asa
0    分が 0 のとき5    時が 5 のとき*    日はどれでも*    月はどれでも*    曜はどれでも

毎日5時0分だね。* は「どれでも」という印だよ(章10の * とは別ものなので、混ぜないでね)。

書ける数の範囲を並べておくね。

範囲
10〜59
20〜23
31〜31
41〜12
50〜6(0 が日曜)

よく使う形を見ておこう。

* * * * *       毎分0 * * * *       毎時0分(1時間ごと)0 5 * * *       毎日5時0 5 * * 1       毎週月曜の5時0 5 1 * *       毎月1日の5時*/5 * * * *     5分ごと0 9,17 * * *    9時と17時0 9-17 * * *    9時から17時まで毎時

下の3つが便利な書き方だよ。

*/5    5 で割り切れるときだけ(0,5,10,…)9,17   どちらか(カンマで並べる)9-17   その範囲(ハイフンでつなぐ)

いちばんはまるのはここだよ。

5 * * * *     毎時5分(1時間に1回)*/5 * * * *   5分ごと(1時間に12回)

上を書いて「5分ごと」のつもりになる人が多いんだ。1つめの欄は「分がいくつのとき」で、「何分ごと」ではないからね。

03 / 08

あずける・見る・消す

表をあずける道具が crontab だよ。

crontab ファイル    そのファイルの中身をあずけるcrontab -l          いまあずけてある表を見るcrontab -r          全部消すcrontab -e          その場で編集する(vi が開く)

打ってみようか。

~ $ echo "0 5 * * * /bin/echo asa" > yotei.txt~ $ crontab yotei.txt~ $ crontab -l0 5 * * * /bin/echo asa

ファイルを書いて、あずけるという流れだね。

この形を使う理由が2つあるよ。

1. 表がファイルとして手元に残る(見返せる・直せる)2. crontab -e は vi が開く(次の章で覚えるので、今日はまだ)

1つめは実務でも大事だよ。あずけた表だけが正だと、うっかり -r したときに何も残らないでしょう。ファイルに書いておけば、crontab yotei.txt でもう一度あずけられるね。

落とし穴が1つあるよ。

crontab atarashii.txt

これは置きかえなんだ。前にあずけた表は消えるよ。

前の表   0 5 * * * A         ↓ crontab betsu.txt(B と書いてある)いまの表  0 6 * * * B      ← A は消えた!

追記ではないでしょう。だから足したいときは、ファイルに全部の行を書いてから、あずけ直すんだ。

crontab -l > ima.txt          いまの表を取り出すecho "0 6 * * * B" >> ima.txt  足すcrontab ima.txt               あずけ直す

取り出して、足して、あずけ直すという3手だね。章4でやったリダイレクトが、ここで役に立つでしょう。

04 / 08

cron の中は別の世界

ここが cron でいちばんはまるところだよ。

> cron から動くとき、あなたの端末とは別の環境になる

何が違うのか、3つ見ておこう。

1. 環境変数が違う

この環境で実際に比べると、こうなっているよ。

変数端末cron の中
PATH/bin:/sbin:/usr/bin:/usr/sbin/sbin:/usr/sbin:/bin:/usr/bin
TERMxtermvt102
LANGC.UTF-8無い
EDITOR/bin/vi無い
PS1\w $無い

別に作られているでしょう。あなたが export した変数も、.profile に書いた設定も届かないんだ。章10で覚えた「環境変数は親から子へ」を思い出してね。cron の親は crond で、あなたのシェルではないでしょう。

だから作法はこうだよ。

* * * * * /bin/echo x        フルパスで書く

PATH に頼らずに書けば、環境が違っても動くね。

2. 場所はホーム

PWD=/home/manabiya

あなたがどこにいても、cron の中ではホームから始まるんだ。だから相対パスを書くときは、ホームからのつもりで書くんだよ。心配ならフルパスにしておくといいね。

3. 出力がどこにも出ない

これがいちばん驚くところだよ。

* * * * * /bin/echo konnichiwa

これを入れても、画面に何も出ない。あなたの端末とはつながっていないでしょう。出力は捨てられてしまうんだ。

本物のサーバーでは、この出力はメールで届く仕組みになっている。でもこの環境にはメールの道具が無いので、静かに消えるんだよ。

だから、こう書くんだ。

* * * * * /bin/echo konnichiwa >> /home/manabiya/kekka.log 2>&1

自分でファイルに残すのが作法だね。2>&1 を付けるのも大事だよ(章4でやったね)。エラーだけ消えると、失敗に気づけないでしょう。

05 / 08

動いたかどうかを確かめる

出力が消えるなら、どうやって確かめるのかというと、記録を見るんだ。

~ $ grep crond /var/log/messages… crond[77]: crond (busybox 1.37.0) started, log level 8… crond[77]: USER manabiya pid 88 cmd /bin/echo tick

下の行が「動かしたよ」という記録だよ。

USER manabiya    誰の表かpid 88           何番で動かしたかcmd /bin/echo …  何を動かしたか

動かしたことは記録に残るんだ。でも、よく見てね。

記録に残る    → 動かしたこと記録に残らない → その結果(出力・成否)

うまくいったかどうかは分からないでしょう。だから章11で覚えた終了ステータスを使うんだ。

* * * * * /home/manabiya/tenken.sh >> /home/manabiya/tenken.log 2>&1 || /bin/echo NG >> /home/manabiya/shippai.log

失敗したら別のファイルに残すでしょう。あとで shippai.log を見れば分かるね。

次のレッスンで logger という道具を覚えると、これをもっときれいに書けるようになるよ。

動かないときの見どころも並べておくね。

症状よくある原因
何も起きない時刻の欄がまちがっている
記録はあるが結果が無い出力をリダイレクトしていない
not foundフルパスで書いていない
実行できないchmod +x を忘れている

そして、いちばん効く確かめ方はこれだよ。

> cron に入れる前に、その1行を手で打ってみる

手で打って動かないものが、cron で動くことはないでしょう。先に手で試すのが遠回りに見えていちばん速いんだ。

06 / 08

章11とつながる

ここで、章11で書いたスクリプトが生きてくるよ。

#!/bin/shset -euDATE=$(date "+%Y-%m-%d")KAZU=$(ls /home/manabiya | wc -l)echo "$DATE $KAZU" >> /home/manabiya/kiroku.log

これを cron に入れると、こうなるね。

0 5 * * * /home/manabiya/kiroku.sh

毎朝5時に、その日のファイル数が記録されるでしょう。あなたが寝ているあいだにね。

これが「仕組みを作る」ということだよ。

道具(スクリプト) + 時刻(cron) = 仕組み

どちらか片方では足りないんだ。

スクリプトだけ    毎回自分で打つcron だけ         1行しか書けなくて複雑なことができない

両方あると、手を離せるようになるでしょう。

cron に入れるスクリプトの作法を3つ渡しておくね。

1. フルパスで書く(PATH に頼らない)2. set -eu を書く(失敗に気づける)3. 出力を残す(>> log 2>&1)

そして、いちばん大事な作法。

> 短く、何度動かしても同じ結果になるように書く

なぜかというと、cron はずれて2回動くことがあるし、前回が終わる前に次が始まることもあるからだよ。

>> で足す     何度動かしても足されるだけ(安全)> で上書き    最後のものだけ残る(安全)rm -rf …      2つ同時に動くと事故(危ない)

何度やっても壊れない形にしておくと、安心して手を離せるね。

07 / 08

毎分にしない

最後に、練習と実務の違いを1つ話しておくね。

この回の練習では、こう書くよ。

* * * * *      毎分

動いたことをすぐ確かめたいからだね。でも実務では毎分にしないんだ。

毎分動かす  ↓ 1日 1440 回  ↓ 少し重い仕事なら、それだけで機械が忙しくなる  ↓ 前回が終わる前に次が始まる

必要な間隔を考えて決めるんだよ。

毎分でないと困る?     → ほとんどの仕事は違う5分ごとで足りる?      → */51日1回で足りる?       → 0 5 * * *

いちばん長い間隔を選ぶのが作法だね。

もう1つ、時刻をずらす作法もあるよ。

0 0 * * *      みんなが選ぶ(0時0分)7 3 * * *      ずらす

きりのいい時刻はみんなが選ぶので、そこだけ機械が忙しくなるんだ。わざと変な数にしておくと、ぶつからないでしょう。

そして練習のあとは、必ず片づけてね。

crontab -r

毎分動く表を入れっぱなしにすると、ログがどんどん増えていくよ。入れたら消すまで1組だと覚えておこう。

08 / 08

さあ、打ってみよう

この回で使う形をまとめておくね。

crontab yotei.txt      表をあずける(置きかえ)crontab -l             いまの表を見るcrontab -r             全部消す分 時 日 月 曜 コマンド  1行の形*                      どれでも*/5                    5 ごと9,17                   どちらか9-17                   その範囲>> log 2>&1            出力を残す

確かめ方も並べておくよ。

ps -o pid,args | grep crond      係が動いているかgrep crond /var/log/messages     動かした記録

今日いちばん覚えてほしいことは3つだよ。

1. 1つめの欄は「分がいくつのとき」(何分ごと、ではない)2. crontab ファイル は置きかえ(追記ではない)3. 出力は自分で残さないと消える

そして今日の結論。

> 時刻をあずけると、手を離せる

1分ごとに時計を見る係が、すでに動いているんだ。あなたはやることを1行書いてあずけるだけでいいんだよ。

この回には1分待つ問題が2つあるよ。cron は分をまたがないと動かないので、待っているあいだは正しいんだ。じっと待ってみてね。

次のレッスンでは logger を覚えるよ。cron で動かしたものの記録を、きちんと残す道具だね。では打ってみよう。