Linux® システムと UNIX® システムでは、1 度だけ、あるいは繰り返しのスケジュールで、ジョブをスケジューリングすることができます。この記事は developerWorks のチュートリアルLPI exam 102 prep: Administrative tasksの抜粋として、定期的にジョブをスケジューリングする方法と、将来のある時点でジョブを実行する方法について説明します。
Linux システムでは、多くの管理タスクを頻繁かつ定期的に行う必要があります。これらのタスクには、ファイルシステムが一杯にならないようにログ・ファイルのローテーションをすることや、データのバックアップ、システム時刻の同期を保つためにタイム・サーバーに接続することなどが含まれます。これらの管理タスクの詳細については、上記の完全なチュートリアルを参照してください。このヒントでは、Linux で利用可能なスケジューリング機能として、cron
機能と anacron
機能、そして crontab
コマンドと at
コマンドの使い方について学びます。たとえシステムがスリープ状態あるいはオフであったとしても、anacron
は次にシステムが稼働状態になった時に指定のジョブを実行してくれます。
定期的にジョブを実行する
定期的にジョブを実行するための管理は cron 機能によって行われます。cron 機能は、crond
デーモンと、どんな作業をどんな頻度で実行すべきかを記述した一連のテーブルで構成されます。このデーモンは毎分ウェイクアップして crontab
をチェックし、何をすべきかを判断します。ユーザーは crontab
コマンドを使って crontab を管理します。crond
デーモンは通常、システム起動時に init プロセスによって起動されます。
話を簡単にするために、リスト 1 に示すコマンドを定期的に実行したいとしましょう。このコマンドは日と時刻をレポートする以外には実際は何もしませんが、これを見ると crontab
を使って cron ジョブを設定する方法がわかります。またこのコマンドがいつ実行されたかは、出力を見るとわかります。crontab エントリーを設定するためには、エスケープしたシェル・メタキャラクターを持つストリングが必要です。そのため、設定には単純なコマンドとパラメーターを使うのが一番です。この例では、スクリプト /home/ian/mycrontab.sh の中から、パラメーターを持たない echo
コマンドが実行されます。こうすると、エスケープ文字を使って注意深い作業をする必要がなくなります。
リスト 1. 単純なコマンドの例
[ian@lyrebird ~]$ cat mycrontest.sh #!/bin/bash echo "It is now $(date +%T) on $(date +%A)" [ian@lyrebird ~]$ ./mycrontest.sh It is now 18:37:42 on Friday
crontab を作成する
crontab
を作成するためには、-e
(「edit」を意味します) オプションを付けた crontab コマンドを使います。これによって、(EDITOR あるいは VISUAL
環境変数の中で別のエディターを指定していない限り)vi
エディターが開きます。
各 crontab エントリーは次の 6 つのフィールドを含んでいます。
- 分
- 時間
- 日
- 月
- 曜日
sh
によって実行されるストリング
分と時間の範囲はそれぞれ 0 から 59 と 0 から 12 ですが、日と月は、それぞれ 1 から 31 と 1 から 12 です。曜日の範囲は 0 から 6 であり、0 が日曜日です。曜日は sun、mon、tue のように指定することもできます。6 番目のフィールドは 5 番目のフィールド以降のすべてであり、sh
に渡すためのストリングとして解釈されます。パーセント記号 (%) は改行に変換されるため、% あるいは他の特殊文字が必要な場合には、その文字の前にバックスラッシュ (\) を置きます。最初の % までの行はシェルに渡されますが、% の後のすべての行は標準入力として渡されます。
時間に関係するさまざまなフィールドでは、個々の値や、ある範囲の値 (0 から 10 まで、あるいは sun から wed までなど)、あるいは個々の値とある範囲の値をカンマで区切ったリストを指定することができます。ここで作成したサンプル・コマンド用の crontab エントリーは少し人工的ですが、リスト 2 のようになります。
リスト 2. 単純な crontab の例
0,20,40 22-23 * 7 fri-sat /home/ian/mycrontest.sh
この例のコマンドは、7 月中の金曜日と土曜日の午後 10 時から午前零時の間の、0 分と 20 分、そして 40 分 (20 分ごと) に実行されます。時刻を指定するための他の方法の詳細については、crontab(5) の man ページを参照してください。
出力はどうなのか
コマンドからの出力がどうなるのか、気になる人もいるかもしれません。cron 機能で使うために設計された大部分のコマンドは、syslog 機能を使って出力をログに記録します (syslog 機能はチュートリアル「LPI exam 102 prep: Administrative tasks」に解説されています)。しかし stdout に送信される出力は、ユーザーにメールされます。リスト 3 は、このサンプル・コマンドから受信される出力を示しています。
リスト 3. メールされた cron 出力
From ian@lyrebird.raleigh.ibm.com Fri Jul 6 23:00:02 2007 Date: Fri, 6 Jul 2007 23:00:01 -0400 From: root@lyrebird.raleigh.ibm.com (Cron Daemon) To: ian@lyrebird.raleigh.ibm.com Subject: Cron <ian@lyrebird> /home/ian/mycrontest.sh Content-Type: text/plain; charset=UTF-8 Auto-Submitted: auto-generated X-Cron-Env: <SHELL=/bin/sh> X-Cron-Env: <HOME=/home/ian> X-Cron-Env: <PATH=/usr/bin:/bin> X-Cron-Env: <LOGNAME=ian> X-Cron-Env: <USER=ian> It is now 23:00:01 on Friday
crontab はどこにあるのか
crontab
コマンドで作成された crontab
は、それを作成したユーザー名の下の /etc/spool/cron に保存されます。そのため、上の crontab は /etc/spool/cron/ian に保存されます。これを考えると、crontab コマンドが passwd
コマンドと同じようにルート権限で実行する suid プログラムであることを知っても驚く人はいないかもしれません。
/etc/crontab
cron
cron は、/var/spool/cron にある (ユーザーの) crontab ファイルの他に、/etc/crontab と、/etc/cron.d ディレクトリーのファイルもチェックします。このようなシステムの crontab には、5 番目の時刻エントリー (日) とコマンドとの間に、もう 1 つ追加のフィールドがあります。この追加フィールドは、コマンドの実行対象であるユーザー (通常はルート) を指定します。/etc/crontab はリスト 4 の例のようになります。
例 4. /etc/crontab
SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ # run-parts 01 * * * * root run-parts /etc/cron.hourly 02 4 * * * root run-parts /etc/cron.daily 22 4 * * 0 root run-parts /etc/cron.weekly 42 4 1 * * root run-parts /etc/cron.monthly
この例では、実際の作業は run-parts
コマンドによって行われます。run-parts コマンドは、/etc/cron.hourly や /etc/cron.daily などのスクリプトを実行します。/etc/crontab は単純に、繰り返し発生するジョブのタイミングをコントロールします。ここに示したコマンドはすべてルートとして実行されることに注意してください。また、crontab にはコマンドが実行される前に設定されるシェル変数割り当ても含まれることに注意してください。
anacron
cron 機能は、連続的に実行されるシステムで適切に動作します。大部分の時間オフされているシステム (ラップトップなど) の場合は、もう 1 つの機能である anacron (「anachronistic cron (遅れて実行される cron)」の意味) を使って、通常は cron 機能によって毎日あるいは毎週、あるいは毎月実行されるジョブをスケジューリングします。anacron は毎時実行されるジョブを処理することはできません。
anacron は /var/spool/anacron にタイムスタンプ・ファイルを保持し、いつジョブが実行されるかを記録します。anacron は実行されると、前回ジョブが実行されてから必要な日数が経過したかどうかをチェックし、もし必要であればジョブを実行します。anacron 用のジョブのテーブルは /etc/anacrontab に保存されます (/etc/anacrontab のフォーマットは /etc/crontab とは少し異なります)。/etc/anacrontab は /etc/crontab と同じように環境設定を含みます。各ジョブには次の 4 つのフィールドがあります。
- period (周期)
- delay (遅延)
- job-identifier (ジョブ ID)
- command (コマンド)
period は日数ですが、@monthly と指定すると、月の日数によらず毎月 1 度だけジョブを実行させることができます。delay は、ジョブの実行を実際に開始する前に何分待つかを指定します。これを利用すると、システムが最初に起動した時に大量のジョブが一斉に起動されるのを防ぐことができます。ジョブ ID はスラッシュ (/) と空白を除く任意の文字を含むことができます。
/etc/crontab も /etc/anacrontab も、直接編集して更新することができます。これらのファイルや /etc/cron.d ディレクトリーのファイルを更新するためには、crontab
crontab コマンドは使いません。
特定の時刻にジョブを実行する
場合によると、定期的にジョブを実行するのではなく、1 度だけ実行したいことがあります。このためには at
コマンドを使います。実行するコマンドは -f
オプションで指定されたファイルから、あるいは -f
が使われていない場合には stdin から読み取られます。-m
オプションは、コマンドによる stdout がない場合にもユーザーにメールを送信します。-v
オプションは、ジョブを読み取る前に、ジョブが実行される時刻を表示します。この時刻は出力にも表示されます。
リスト 5 は、先ほど使用したmycrontest.sh
スクリプトを実行する例を示しています。リスト 6 は、ジョブが実行された後にユーザーにメールで返送される出力を示しています。この出力が cron ジョブでの出力よりも少しコンパクトなことに注目してください。
リスト 5. at コマンドを使う
[ian@lyrebird ~]$ at -f mycrontest.sh -v 10:25 Sat Jul 7 10:25:00 2007 job 5 at Sat Jul 7 10:25:00 2007
リスト 6. at からのジョブ出力
From ian@lyrebird.raleigh.ibm.com Sat Jul 7 10:25:00 2007 Date: Sat, 7 Jul 2007 10:25:00 -0400 From: Ian Shields <ian@lyrebird.raleigh.ibm.com> Subject: Output from your job 5 To: ian@lyrebird.raleigh.ibm.com It is now 10:25:00 on Saturday
時刻の仕様は非常に複雑です。リスト 7 は、そうしたいくつかの例を示しています。詳しくは、at
やファイル /usr/share/doc/at/timespec、あるいは /usr/share/doc/at-3.1.10/timespec などのファイルの man ページを参照してください (この例での 3.1.10 は at
パッケージのバージョンを示します)。
リスト 7. at コマンドでの時刻の値
[ian@lyrebird ~]$ at -f mycrontest.sh 10pm tomorrow job 14 at Sun Jul 8 22:00:00 2007 [ian@lyrebird ~]$ at -f mycrontest.sh 2:00 tuesday job 15 at Tue Jul 10 02:00:00 2007 [ian@lyrebird ~]$ at -f mycrontest.sh 2:00 july 11 job 16 at Wed Jul 11 02:00:00 2007 [ian@lyrebird ~]$ at -f mycrontest.sh 2:00 next week job 17 at Sat Jul 14 02:00:00 2007
at コマンドには -q
オプションもあります。キューを増加するとジョブの nice
値が増加します。また、batch
コマンドもあります。batch コマンドは at
コマンドと似ていますが、システム負荷が十分低い時だけジョブが実行される点が異なります。これらの機能の詳細については man ページを参照してください。
スケジュール・ジョブを管理する
スケジュール・ジョブをリストする
cron ジョブと at ジョブの動作は、管理することができます。crontab
コマンドに -l
オプションを付けると crontab
をリストでき、また atq
コマンドを使うと、at
コマンドを使ってキューに入れられたジョブを表示することができます (リスト 8)。
リスト 8. スケジュール・ジョブを表示する
[ian@lyrebird ~]$ crontab -l 0,20,40 22-23 * 7 fri-sat /home/ian/mycrontest.sh [ian@lyrebird ~]$ atq 16 Wed Jul 11 02:00:00 2007 a ian 17 Sat Jul 14 02:00:00 2007 a ian 14 Sun Jul 8 22:00:00 2007 a ian 15 Tue Jul 10 02:00:00 2007 a ian
at
によって実行のスケジューリングを行った実際のコマンドを確認したい場合には、-c
オプションとジョブ番号を付けた at
コマンドを使います。at
コマンドが発行された時にアクティブだった大部分の環境が、スケジューリングされたジョブと共に保存されることがわかると思います。リスト 9 は、リスト
7 と 8 のジョブ 15 の出力の一部を示しています。
リスト 9. ジョブ番号を付けた at -c を使う
#!/bin/sh # atrun uid=500 gid=500 # mail ian 0 umask 2 HOSTNAME=lyrebird.raleigh.ibm.com; export HOSTNAME SHELL=/bin/bash; export SHELL HISTSIZE=1000; export HISTSIZE SSH_CLIENT=9.67.219.151\ 3210\ 22; export SSH_CLIENT SSH_TTY=/dev/pts/5; export SSH_TTY USER=ian; export USER ... HOME=/home/ian; export HOME LOGNAME=ian; export LOGNAME ... cd /home/ian || { echo 'Execution directory inaccessible' >&2 exit 1 } ${SHELL:-/bin/sh} << `(dd if=/dev/urandom count=200 bs=1 \ 2>/dev/null|LC_ALL=C tr -d -c '[:alnum:]')` #!/bin/bash echo "It is now $(date +%T) on $(date +%A)"
このスクリプト・ファイルの内容が、here 文書としてコピーされていることに注意してください (この文書は、SHELL 変数で指定されるシェルによって、あるいは SHELL 変数が設定されていない場合には /bin/sh によって実行されます)。here 文書について調べる場合は、チュートリアル「LPI exam 101 prep, Topic 103: GNU and UNIX commands」を参照してください。
スケジュール・ジョブを削除する
-r
オプションを付けた cron
コマンドを使うと、スケジュールされたすべての cron ジョブを削除することができます (リスト 10)。
リスト 10. cron ジョブを表示し、削除する
[ian@lyrebird ~]$ crontab -l 0,20,40 22-23 * 7 fri-sat /home/ian/mycrontest.sh [ian@lyrebird ~]$ crontab -r [ian@lyrebird ~]$ crontab -l no crontab for ian
システムの cron ジョブあるいは anacron ジョブを削除するためには、/etc/crontab あるいは /etc/anacrontab を編集するか、あるいは /etc/cron.d ディレクトリーの中のファイルを編集または削除します。
at
コマンドでスケジューリングされたジョブを 1 つもしくは複数、削除するには、ジョブ番号を付けたatrm
コマンドを使います。複数のジョブは空白で区切ります。リスト 11 はその一例を示しています。
リスト 11. atq と atrm を使ってジョブを表示し、削除する
[ian@lyrebird ~]$ atq 16 Wed Jul 11 02:00:00 2007 a ian 17 Sat Jul 14 02:00:00 2007 a ian 14 Sun Jul 8 22:00:00 2007 a ian 15 Tue Jul 10 02:00:00 2007 a ian [ian@lyrebird ~]$ atrm 16 14 15 [ian@lyrebird ~]$ atq 17 Sat Jul 14 02:00:00 2007 a ian
ジョブ・スケジューリングへのユーザー・アクセスを構成する
/etc/cron.allow ファイルが存在する場合には、crontab
と cron 機能を使うためには、このファイルの中にルート以外の全ユーザーをリストする必要があります。/etc/cron.allow ファイルが存在せず
/etc/cron.deny ファイルが存在する場合には、/etc/cron.deny の中にリストされたルート以外のユーザーは、crontab
あるいは cron 機能を使うことができません。もしどちらのファイルも存在しない場合には、このコマンドを使えるのはスーパー・ユーザーのみです。/etc/cron.deny
ファイルが空の場合には、すべてのユーザーが cron 機能を使うことができます。デフォルトでは /etc/cron.deny ファイルは空です。
これに対応する /etc/at.allow ファイルと /etc/at.deny ファイルも、at 機能に対して同様の効果を持っています。
さらに学ぶためには
Linux の管理タスクについて詳しく知りたい方は、チュートリアル「LPI exam 102 prep: Administrative tasks」を読んでください (この記事はこのチュートリアルを抜粋したものです)。あるいは下記の「参考文献」を参照してください。また、この記事を評価することも忘れないでください。
参考文献
学ぶために
- チュートリアル「LPI exam 102 prep: Administrative tasks」(developerWorks、2007年7月) では、Linux での他の管理タスク (ユーザー管理やバックアップ、システム・ログ、Network Time Protocol など) について学ぶことができます。このチュートリアルは、Linux の基本を網羅した、またシステム・アドミニストレーター認定を受ける準備のための、LPI exam prep tutorial series の一部です。この記事で参照した、同じシリーズの他のチュートリアルとして、「LPI exam 101 prep: GNU and UNIX commands」 と 「LPI exam 101 prep: Devices, Linux filesystems」、そして「Filesystem Hierarchy Standard」があります。
- developerWorks の Linux ゾーンには、Linux のチュートリアルや、先月公開された Linux についての記事とチュートリアルの中から読者が選んだ上位 10 位までのリストを含め、他にも Linux 開発者のためのリソースが豊富に用意されています。
- developerWorks technical events and Webcastsで最新情報を入手してください。
製品や技術を入手するために
- developerWorks から直接ダウンロードできるIBM ソフトウェア評価版を利用して、皆さんの次期 Linux 開発プロジェクトを構築してください。
議論するために
- ディスカッション・フォーラムに参加してください。
- 開発者のブログやフォーラム、ポッドキャスト、などを通して、developerWorks のコミュニティーに加わってください。
コメント
IBM PureSystems
IBM がどのように IT に革命をもたらしているのかをご自身でお確かめください
Knowledge path
developerWorks の Knowledge path シリーズでは、テーマ別の学習資料をご提供しています
ソフトウェア評価版: ダウンロード
developerWorksでIBM製品をお試しください!