crontabの設定メモ
crontabの設定は簡単なのだが、ちゃんと理解しようとすると意外と多くの関連する知識が必要なのであった...。以下、crontabの設定しながら覚えたことメモ。
関連する日記
コマンド書式
crontab -l # zariユーザーのcron設定を表示する crontab -e # zariユーザーのcron設定をviを起動して編集する sudo crontab -u Guest -l # ルート権限で認証して、Guestユーザーのcron設定を表示する
- 実行する時間の設定とコマンドから構成される。
* * * * * command | | | | | | | | | `--曜日(0:日 1:月 2:火 3:水 4:木 5:金 6:土 7:日) | | | `----月 | | `------日 | `--------時 `----------分 例: * * * * * command #1分ごとに実行する */2 * * * * command #2分ごとに実行する 2 * * * * command #毎時2分に実行する(分の単位が2の場合実行) 10,50 * * * * command #毎時10分と50分に実行する(分の単位が10と50の場合実行) 2 0-6 * * * command #毎日0時から6時は、2分に実行する(分の単位が2、かつ、時の単位が0から6の場合実行)
以下、関連する知識...
標準入力・標準出力・標準エラー出力
- ターミナルでコマンドを実行すると、コマンドによっては何らかの情報を返してくる。
- 特に指定しない限り、上記のように返された文字情報は、ターミナルのウィンドウに表示されてコマンド利用者に何かを伝えてくれる。
- シェル内部では、これらの情報を標準出力、標準エラー出力という概念で取り扱っているらしい。
- 何も指定がない場合、標準出力、標準エラー出力とも端末(画面)に表示されるようになっている。
- もし、以下のように指定すれば、出力先にファイルが指定されたことになり、ファイル名:my_textとして保存される。
$ ls >my_text*2 $ cat my_text Desktop Documents Downloads Library ...
-
- ちなみに、標準入力という概念もあって、これは通常キーボードになっている。
$ read DATA 123 #123とキー入力した $ echo $DATA 123 $ read DATA <in_text #ファイルin_textには"ABC"が保存されている $ echo $DATA ABC
-
-
- read DATA 後の 123 が標準入力のキーボードから入力され、変数DATA に格納される。
-
-
-
- lsの引数も標準入力をファイルに切り替えて設定できそうな気になるが、
-
$ ls <in_text
-
-
- lsコマンドは引数がない場合もそのまま実行して、単に引数なしのlsが実行された結果が返ることになる。
- 標準入力のリダイレクトが利用できるのは、標準入力を引数として利用できるコマンドの場合のみ。(read、cat、more、less、sort...等)
-
$ sl 2>in_text $ cat in_text -bash: abc: command not found
-
- 標準出力、標準エラー出力の両方ともファイルに保存する場合は、>& も利用できる。
$ echo sample_text >abc $ cat abc xyz >&my_text $ cat my_text sample_text cat: xyz: No such file or directory
>file_name | 標準出力をfile_nameに上書き |
2>>file_name | 標準エラー出力をfile_nameの末尾に追記 |
>&file_name | 標準出力と標準エラー出力をfile_nameに上書き |
>&num | 標準出力をファイルディスクリプタ番号numと同じファイルやデバイスに出力する |
num1>&num2 | ファイルディスクリプタ番号num1をファイルディスクリプタ番号num2と同じファイルやデバイスに出力する |
>/dev/null 2>&1 | 標準出力と標準エラー出力を破棄する (標準出力が/dev/nullにセットされ実行、標準エラー出力は標準出力(左記より/dev/null)にセットされ実行) |
ファイルディスクリプタ
- cronで予約設定したコマンドを実行する時にも、様々な情報が返される可能性がある。
- しかし、標準出力や標準エラー出力が画面のままでは、返される情報を確認することが出来ない。
- そこで、cronは標準出力や標準エラー出力が発生した場合、その情報を各ログインユーザー宛のメールで送信してくれる。
- そのメールはmailコマンドで確認できる。
- mailコマンド実行中の指示コマンド(mailコマンド実行後、?プロンプトが表示されていればメールを閲覧するモード)
指示コマンド | 機能 |
---|---|
? | コマンド一覧表示 |
[メール番号] | [メール番号]のメールを表示する(既読になる) |
v | 選択カーソル > が示すメールを、エディタ(例:vi)で表示する(既読になる) |
v[メール番号] | [メール番号]のメールを、エディタ(例:vi)で表示する(既読になる) |
f[メール番号] | 行先頭の選択カーソル > を、[メール番号]に移動する(未読のまま) |
h | 現在の選択カーソル > の位置を含むメールリスト表示する |
s | 選択カーソル > が示すメールを、~/mboxの末尾へ保存する |
s[ファイル名] | 選択カーソル > が示すメールを、[ファイル名]の末尾へ保存する |
s[メール番号] [ファイル名] | [メール番号]のメールを[ファイル名]の末尾へ保存する |
d | 選択カーソル > が示すメールを削除する |
d[メール番号] | [メール番号]のメールを削除する |
q | 現在の状態を保存して終了。(既読メールはmboxへ、削除メールは削除される) |
x | 現在の状態を破棄して終了。(mailコマンド実行前の状態に戻る。) |
- メールリストが1ページ以上ある場合、fでカーソル位置を指定して、hでその周辺をリスト表示することで、目指す位置を表示することができる。
- mailコマンドで一覧表示されるメールは、私書箱(/var/mail/USER_NAME)に届いている未読メールと考えることができる。
- メールが既読になると、私書箱(/var/mail/USER_NAME)から自分の手元(~/mbox)に移動される。
- メールの保存先は、~/mbox以外にも自由に指定できる。(sコマンド)
$ mail Mail version 8.1 6/6/93. Type ? for help. "/var/mail/zari": 52 messages 30 new 52 unread N 1 zari@zari-MacBook.lo Sat Feb 28 07:48 20/852 "Crondiff -q ~/Library/StickiesDatabase ..." N 2 zari@zari-MacBook.lo Mon Mar 2 09:41 20/852 "Cron diff -q ~/Library/StickiesDatabase ..." >N 3 zari@zari-MacBook.lo Mon Mar 2 09:56 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." N 4 zari@zari-MacBook.lo Mon Mar 2 10:53 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." N 5 zari@zari-MacBook.lo Mon Mar 2 11:01 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." N 6 zari@zari-MacBook.lo Mon Mar 2 11:03 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." N 7 zari@zari-MacBook.lo Mon Mar 2 11:08 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." N 8 zari@zari-MacBook.lo Mon Mar 2 11:10 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." N 9 zari@zari-MacBook.lo Mon Mar 2 11:14 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." N 10 zari@zari-MacBook.lo Mon Mar 2 11:18 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." N 11 zari@zari-MacBook.lo Mon Mar 2 11:20 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." N 12 zari@zari-MacBook.lo Mon Mar 2 11:25 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." N 13 zari@zari-MacBook.lo Mon Mar 2 11:29 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." N 14 zari@zari-MacBook.lo Mon Mar 2 11:31 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." N 15 zari@zari-MacBook.lo Mon Mar 2 11:38 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." N 16 zari@zari-MacBook.lo Mon Mar 2 11:42 19/842 "Cron diff -q ~/Library/StickiesDatabase ..." ? ? Mail Commands t type messages n goto and type next message e edit messages f give head lines of messages d delete messages s file append messages to file u undelete messages R reply to message senders r reply to message senders and all recipients pre make messages go back to /var/mail m mail to specific users q quit, saving unresolved messages in mbox x quit, do not remove system mailbox h print out active message headers ! shell escape cd [directory] chdir to directory or home if none given A consists of integers, ranges of same, or user names separated by spaces. If omitted, Mail uses the last message typed. A consists of user names or aliases separated by spaces. Aliases are defined in .mailrc in your home directory. ? 1 Message 1: From zari@zari-MacBook.local Sat Feb 28 07:48:03 2009 X-Original-To: zari Delivered-To: zari@zari-MacBook.local From: zari@zari-MacBook.local (Cron Daemon) To: zari@zari-MacBook.local Subject: Cron diff -q ~/Library/StickiesDatabase ~/Documents/StickiesData.aaa || cp ~/Library/StickiesDatabase ~/Documents/StickiesData.aaa X-Cron-Env: X-Cron-Env: X-Cron-Env: X-Cron-Env: X-Cron-Env: Date: Sat, 28 Feb 2009 07:48:02 +0900 (JST) Files /Users/zari/Library/StickiesDatabase and /Users/zari/Documents/StickiesData.aaa differ
- mail -fオプションで、ファイル~/mboxに移動されたメールを閲覧するモードになる。
- mail -f FILE_NAMEオプションで、FILE_NAMEに保存されたメールを閲覧するモードになる。
- mail -u USER_NAMEオプションで指定したユーザーのメールも確認できる。(管理者権限必要)
$ sudo mail -u Guest
不要なmail
- mailはコマンドが返す情報を伝えてくれる便利な仕組みなのだが、時には悩みの種になることがある。
- 例えば、Spotlight検索を実現するために1分毎に実行するStickiesDatabaseのコピー処理なんかは、放っておくとあっという間にmailのサイズが馬鹿でかくなる。
- メールの内容は「StickiesDatabaseが見つからない」なのだが、そんなことは重要ではなく、不要なのだ。(コピーできる時にコピーしてくれるだけで十分)
- そんな時は、標準出力や標準エラー出力を破棄してしまう方法がある。
- リダイレクト指定の >/dev/null 2>&1 をコマンドごとに付加すればOK。
* * * * * diff -q ~/Library/StickiesDatabase ~/Documents/StickiesData.aaa >/dev/null 2>&1 || cp ~/Library/StickiesDatabase ~/Documents/StickiesData.aaa >/dev/null 2>&1
- または、cronの環境変数 MAILTO="" を指定する。(定期的に実行するコマンドよりも上で(先に)指定しておく)
- 標準出力・標準エラー出力は発生するが、メールの送信先が""なので、どこにも送信されないことになる。
- MAILTO="" を指定した後の、すべてのコマンドでメールは送信されない。
MAILTO="" * * * * * diff -q ~/Library/StickiesDatabase ~/Documents/StickiesData.aaa || cp ~/Library/StickiesDatabase ~/Documents/StickiesData.aaa
- 参考ページ:
test
- 利用例:~/Library/StickiesDatabaseが存在すれば、コピーする。
* * * * * test -e ~/Library/StickiesDatabase && cp ~/Library/StickiesDatabase ~/Documents/StickiesData.aaa
- 数値・文字列・ファイルを比較する時に利用される。様々な比較オプションがある。
オプション | 予想される単語 | 例 | 意味 |
---|---|---|---|
-e | exist | test -e file | ファイルが存在すれば真 |
-s | size | test -s file | ファイルが0より大きいサイズなら真 |
-f | file | test -f file | ファイルであれば真 |
-d | directory | test -d file | ファイルがディレクトリであれば真 |
-r | read | test -r file | ファイルの権限が読み取り可能であれば真 |
-w | write | test -w file | ファイルの権限が書き込み可能であれば真 |
-x | execute | test -x file | ファイルの権限が実行可能であれば真 |
-nt | newer than | test file1 -nt file2 | ファイル1の方が新しければ真(ファイル2と比較して) |
-ot | older than | test file1 -ot file2 | ファイル1の方が古ければ真(ファイル2と比較して) |
-z | zero | test -z str | 文字列のサイズが0ならば真 |
-n | not zero | test -n str | 文字列のサイズが0より大きければ真 |
= | test str1 = str2 | 文字列1と文字列2が等しければ真 | |
!= | test str1 != str2 | 文字列1と文字列2が等しくなければ真 | |
-eq | equal | test num1 -eq num2 | num1=num2なら真 |
-ne | not equal | test num1 -ne num2 | num1≠num2なら真 |
-lt | less than | test num1 -lt num2 | num1 < num2なら真 |
-le | less than or equal | test num1 -le num2 | num1 ≦ num2なら真 |
-gt | greater than | test num1 -gt num2 | num1 > num2なら真 |
-ge | greater than or equal | test num1 -ge num2 | num1 ≧ num2なら真 |
- testコマンドは[]を利用して以下のように書くことも出来る。(上下のペアは同義)
test num1 -eq num2 [ num1 -eq num2 ] test -e ~/Library/StickiesDatabase [ -e ~/Library/StickiesDatabase ]
- [はコマンドなので、[の後と、]の前に必ずスペースを入れる必要あり。
複数コマンドの実行
- コマンド1 ; コマンド2
- コマンド1を実行、終了したら(エラーで終了しても)、コマンド2を実行
cd ~/Desktop;ls -l
- ディレクトリを~/Desktopに移動して、ls -lを実行する。
- コマンド1 && コマンド2
- コマンド1を実行、結果が真であれば、コマンド2を実行
test -e ~/Library/StickiesDatabase && cp ~/Library/StickiesDatabase ~/Documents/StickiesData.aaa
- ~/Library/StickiesDatabaseが存在していたら、コピーする。
- コマンド1 || コマンド2
- コマンド1を実行、結果が偽であれば、コマンド2を実行
test -e ~/Documents/StickiesData.aaa || ln ~/Library/StickiesDatabase ~/Documents/StickiesData.aaa
- ~/Documents/StickiesData.aaaが存在していなければ、ハードリンクを作成する。
- コマンド1 | コマンド2
- コマンド1の標準出力を、コマンド2の標準入力にして実行
ls | wc -l
- lsを実行して、出力される結果に何行あるか数える。(ファイルやディレクトリの数を確認できる。)
- 参考ページ
run-parts
- run-partsコマンドは、指定されたディレクトリに存在するコマンドやシェルスクリプトを順番にすべて実行してくれる。
- MacBook OSX 10.5環境には、run-partsコマンドはプリインストールされていなかった。
periodic
- run_partsコマンドに替わって、osxではperiodicコマンドが利用できるのであった。
*1:実は自分の場合、蒸気機関車のSLが走る!http://d.hatena.ne.jp/zariganitosh/20080702/1214953436
*2:>my_text lsでもOK。>my_textはlsの引数ではない。標準出力を指定するコマンドのようなもの。