Linux のヒント: cron と at を使ったジョブ・スケジューリング

システムが動作している間に人生を楽しむ

皆さんはシステム使用率が低い真夜中にジョブを実行しなければなりません。あるいは毎日、あるいは毎週ジョブを実行しなければならないかもしれません。しかし皆さんは、そんなことをするよりも眠りたい、あるいは他の方法で人生を楽しみたいと思うはずです。そういうときにジョブをスケジューリングすると役立ちますが、ジョブをスケジューリングすると、ルーチン・タスクを自動的に行わせることができたり、またタスクを必ず毎回同じ方法で処理することができます。このヒントでは、定期的に、あるいは将来のある時点で、ジョブが実行されるようにスケジューリングするために、cron 機能と at 機能を使う方法について説明します。

Ian Shields (ishields@us.ibm.com), Senior programmer, IBM

Ian ShieldsIan Shields は、developerWorks Linux ゾーンの様々な Linux プロジェクトに関わっています。彼はノースキャロライナ州 Research Triangle Park にある IBM のシニア・プログラマーです。1973年にオーストラリアのキャンベラでシステム・エンジニアとして IBM に入社して以来、カナダのモントリオールやノースキャロライナ州 Research Triangle Park で、コミュニケーション・システムやパーベイシブ・コンピューティングに携わってきました。彼はいくつかの特許を保持しています。Australian National University にて純粋数学および哲学で学位を取得し、また North Carolina State University にてコンピューター・サイエンスで修士と博士を取得しています。



2007年 7月 18日

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 つのフィールドを含んでいます。

  1. 時間
  2. 曜日
  3. 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 はどこにあるのか

suid プログラム

suid プログラムは、そのプログラムを実行しているユーザーのパーミッションではなく、プログラム・ファイルの所有者のパーミッションによって実行されます。suid について詳しくはチュートリアル「LPI exam 101 prep: Devices, Linux filesystems, and the Filesystem Hierarchy Standard」を、また passwd コマンドについて詳しくは「LPI exam 102 prep: Administrative tasks」を参照してください。

crontab コマンドで作成された crontab は、それを作成したユーザー名の下の /etc/spool/cron に保存されます。そのため、上の crontab は /etc/spool/cron/ian に保存されます。これを考えると、crontab コマンドが passwd コマンドと同じようにルート権限で実行する suid プログラムであることを知っても驚く人はいないかもしれません。

/etc/crontab

croncron は、/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 つのフィールドがあります。

  1. period (周期)
  2. delay (遅延)
  3. job-identifier (ジョブ ID)
  4. command (コマンド)

period は日数ですが、@monthly と指定すると、月の日数によらず毎月 1 度だけジョブを実行させることができます。delay は、ジョブの実行を実際に開始する前に何分待つかを指定します。これを利用すると、システムが最初に起動した時に大量のジョブが一斉に起動されるのを防ぐことができます。ジョブ ID はスラッシュ (/) と空白を除く任意の文字を含むことができます。

/etc/crontab も /etc/anacrontab も、直接編集して更新することができます。これらのファイルや /etc/cron.d ディレクトリーのファイルを更新するためには、crontabcrontab コマンドは使いません。


特定の時刻にジョブを実行する

場合によると、定期的にジョブを実行するのではなく、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

nice 値

ジョブの nice 値は、そのジョブが他のユーザーにとって、どの程度良いものかを示す指標です。nice コマンドと reniceコマンドについての詳細は、チュートリアル「LPI exam 101 prep: GNU and UNIX commands」を参照してください。

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」を読んでください (この記事はこのチュートリアルを抜粋したものです)。あるいは下記の「参考文献」を参照してください。また、この記事を評価することも忘れないでください。

参考文献

学ぶために

製品や技術を入手するために

  • developerWorks から直接ダウンロードできるIBM trial softwareを利用して、皆さんの次期 Linux 開発プロジェクトを構築してください。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux, Open source
ArticleID=251593
ArticleTitle=Linux のヒント: cron と at を使ったジョブ・スケジューリング
publish-date=07182007