Red Hat Enterprise Linux でのタスクのスケジュール

Red Hat Enterprise LinuxBeginner
オンラインで実践に進む

はじめに

この実験(Lab)では、さまざまなツールを使用して RHEL システムでタスクをスケジュールする実践的な経験を積みます。atコマンドを使用して 1 回限りのジョブをスケジュールし、crontabを使用してユーザー固有の繰り返しタスクを管理し、cron ディレクトリを使用してシステム全体の繰り返しジョブを構成する方法を学びます。

さらに、この実験では、より堅牢で柔軟なタスク自動化のためにsystemdタイマーを使用した高度なスケジューリング技術についても取り上げ、systemd-tmpfilesを使用して一時ファイルを効率的に管理する方法を説明します。この実験の終わりには、さまざまなシナリオに適したスケジューリング方法を選択し、RHEL 環境で自動化されたタスクを効果的に管理できるようになります。

これは Guided Lab です。学習と実践を支援するためのステップバイステップの指示を提供します。各ステップを完了し、実践的な経験を積むために、指示に注意深く従ってください。過去のデータによると、この 初級 レベルの実験の完了率は 85%です。学習者から 92% の好評価を得ています。

'at' で 1 回限りのジョブをスケジュールする

このステップでは、将来の特定の時間に一度だけ実行されるようにジョブをスケジュールする方法を at コマンドを使用して学習します。at コマンドは、繰り返し実行する必要のないコマンドを実行する場合に便利です。ここでは、簡単なジョブをスケジュールし、その詳細を確認してから削除します。

この実験 (Lab) では、タスクスケジューリングを学習するために、ローカルシステム上で直接作業を行います。すべてのコマンドは、現在のターミナル環境で実行されます。

まず、現在の現在時刻をホームディレクトリの ~/myjob.txt というファイルに書き込むジョブをスケジュールしましょう。実行は今から 3 分後に設定します。

at now + 3 minutes << EOF
date > ~/myjob.txt
EOF

warning: commands will be executed using /bin/sh というメッセージは正常です。job N at ... という出力は、ジョブ番号とスケジュールされた実行時間を示しています。後で必要になるため、ジョブ番号をメモしておいてください。

次に、別のジョブを対話的にスケジュールしましょう。この方法は、複数のコマンドやより複雑なスクリプトを入力する場合に便利です。今から 5 分後に、~/at_output.txt に "Hello from at job!" という文字列を追記するジョブをスケジュールします。

at now + 5 minutes

コマンドを入力して Enter キーを押すと、at> プロンプトが表示されます。コマンドを入力し、Ctrl+d を押して完了します。

at > echo "Hello from at job!" >> ~/at_output.txt
at > Ctrl+d

現在 at キューにあるジョブを表示するには、atq コマンドを使用します。このコマンドは、現在のユーザーの保留中のすべての at ジョブを一覧表示します。

atq

出力には、ジョブ番号、スケジュールされた時刻、キュー、およびスケジュールしたユーザーが表示されます。

スケジュールされたジョブを示す atq コマンドの出力

特定の at ジョブが実行するコマンドを確認するには、at -c コマンドの後にジョブ番号を指定します。N を、先ほどメモしたジョブ番号のいずれかに置き換えてください。

at -c N

このコマンドは、at がそのジョブに対して実行するシェルスクリプトを表示します。出力の中に、date > ~/myjob.txt または echo "Hello from at job!" >> ~/at_output.txt コマンドが表示されるはずです。

最後に、スケジュールされた at ジョブを削除するには、atrm コマンドの後にジョブ番号を指定します。最初にスケジュールしたジョブを削除しましょう。N を、最初のジョブのジョブ番号に置き換えてください。

atrm N

ジョブを削除した後、再度 atq を使用して、キューから削除されたことを確認できます。

atq

ここでは、2 番目のジョブのみが表示されるはずです(まだ実行されていない場合)。または、両方のジョブが削除または実行された場合は、空のキューが表示されます。

これで、at コマンドを使用した一度きりのジョブのスケジューリングの最初のステップは完了です。

'at' ジョブの管理

このステップでは、異なるキューでのジョブのスケジューリングや実行の検証を含む、at ジョブの管理について詳しく説明します。at キューを理解することは、タスクの優先順位付けや、異なる種類の単発ジョブの分離に役立ちます。

より高度な at ジョブ管理機能を探索するために、ローカルシステムで作業を続けます。

at コマンドは、-q オプションを使用してキューを指定できます。キューは a から z までの単一の文字です。キュー a はデフォルトであり、キュー a から z までのジョブは、niceness(優先度)が低下するにつれて実行されます。キュー a が最も優先度が高く、キュー z が最も優先度が低いです。キュー b はバッチジョブ用に予約されています。

2 分後に実行されるように、キュー g(優先度の低いキュー)にジョブをスケジューリングしましょう。このジョブは、タイムスタンプ付きで ~/queue_g_job.txt という名前のファイルを作成します。

at -q g now + 2 minutes << EOF
date > ~/queue_g_job.txt
EOF

job N at ... のような出力が表示されます。このジョブ番号をメモしておいてください。

次に、システム負荷が低いときに実行できるジョブに使用されることが多いキュー b(バッチキュー)に、別のジョブをスケジューリングしましょう。このジョブは、~/batch_job.txt に "Batch job executed!" を追記します。現在から 4 分後に実行されるようにスケジューリングします。

at -q b now + 4 minutes << EOF
echo "Batch job executed!" >> ~/batch_job.txt
EOF

ここでも、ジョブ番号をメモしておいてください。

保留中のすべてのジョブ(異なるキューのジョブを含む)を表示するには、atq を使用します。

atq

これで、それぞれのキュー文字(gb)とともに、両方のジョブがリストされているはずです。

スケジューリングされたジョブを示す atq コマンドの出力

次に、スケジューリングされたジョブが実行されるのを待ちます。すべてのジョブが完了するのに少なくとも 5 分待ちます。at ジョブによって作成されたファイルが存在し、期待される内容が含まれているかを確認できます。

~/queue_g_job.txt を確認します。

cat ~/queue_g_job.txt

日付と時刻の文字列が表示されるはずです。

~/batch_job.txt を確認します。

cat ~/batch_job.txt

"Batch job executed!" が表示されるはずです。

ファイルが存在しないか空の場合、ジョブがまだ実行されていないか、コマンドに問題があった可能性があります。atq を再確認して、まだ保留中かどうかを確認できます。

これで、高度な at ジョブ管理ステップは完了です。残りの at ジョブは、コンテナが破棄されるときに自動的にクリーンアップされます。

'crontab' で定期的なユーザージョブをスケジュールする

このステップでは、特定のユーザーに対して定期的なタスクをスケジュール設定する方法を crontab を使用して学習します。一度だけ実行される at ジョブとは異なり、cron ジョブは指定された間隔で繰り返し実行されます。これは、定期的なメンテナンス、データバックアップ、またはレポート生成に最適です。

ユーザーの crontab 管理について学習するために、ローカルシステムで作業を続けます。

crontab コマンドを使用すると、ユーザーは自身の cron ジョブを作成、編集、および表示できます。各ユーザーは独自の crontab ファイルを持っています。

crontab ファイルを編集するには、crontab -e コマンドを使用します。これにより、デフォルトのテキストエディタ(通常は vim)で crontab ファイルが開かれます。

crontab -e

Vim エディタの操作方法:

  • i を押して挿入モードに入ります(画面下部に -- INSERT -- と表示されます)。
  • 矢印キーで移動します。
  • 保存して終了するには:Esc を押して挿入モードを終了し、:wq と入力して Enter を押します。
  • 保存せずに終了するには:Esc を押して挿入モードを終了し、:q! と入力して Enter を押します。

エディタ内で、cron ジョブを定義する新しい行を追加します。cron エントリは、実行されるコマンドの前に、5 つの時間と日付のフィールドがあります。フィールドは次のとおりです。

  • 分 (0-59)
  • 時 (0-23)
  • 日 (1-31)
  • 月 (1-12)
  • 曜日 (0-7、0 または 7 は日曜日)

フィールドでは、* をワイルドカードとして「すべて」を意味するために使用できます。また、/ を使用してステップ値を指定できます(例:5 分ごとには */5)。

ここでは、現在の時刻を毎分 ~/my_cron_log.txt という名前のファイルに追加するジョブをスケジュール設定します。これにより、cron ジョブが動作している様子を素早く確認できます。

vim で以下の手順を実行してください。

  1. i を押して挿入モードに入ります。
  2. crontab ファイルに次の行を追加します。
* * * * * /usr/bin/date >> ~/my_cron_log.txt
  1. Esc を押して挿入モードを終了します。
  2. :wq と入力して Enter を押して保存し、終了します。

新しい crontab がインストールされたことを示すメッセージが表示されるはずです。

crontab: installing new crontab

cron ジョブが正常に追加されたことを確認するには、crontab -l コマンドを使用して crontab エントリを一覧表示できます。

crontab -l

追加した行が表示されるはずです。

* * * * * /usr/bin/date >> ~/my_cron_log.txt

ここで、1〜2 分待って cron ジョブが少なくとも一度実行されるようにします。現在の時刻を確認して、次の分単位の区切りがいつになるかを確認できます。

date

cron ジョブが数回実行されるように少なくとも 2 分待った後、~/my_cron_log.txt ファイルの内容を確認します。

cat ~/my_cron_log.txt

日付と時刻を含む 1 行以上の行が表示され、cron ジョブが実行されたことを示しているはずです。

Mon Apr 8 10:30:01 AM EDT 2024
Mon Apr 8 10:31:01 AM EDT 2024
Cron job output in log file

これで、ユーザーの crontab 管理ステップは完了です。コンテナが破棄されるまで、cron ジョブは実行され続けます。

ユーザーの 'crontab' エントリを管理する

このステップでは、既存のジョブの編集、複数のジョブの追加、特別なcron文字列の理解など、ユーザーcrontabエントリを管理するためのより高度なテクニックを学びます。効果的なcrontab管理は、ルーチンタスクを自動化するために不可欠です。

高度な crontab 管理テクニックを探索するために、ローカルシステムで引き続き作業します。

新しいcronジョブを追加することから始めましょう。このジョブは、2 分ごとに"Hello from cron!"~/cron_messages.txtに追加します。

編集のためにcrontabを開きます。

crontab -e

vim で:

  1. iを押して挿入モードに入ります
  2. 次の行をcrontabファイルに追加します。
*/2 * * * * echo "Hello from cron!" >> ~/cron_messages.txt
  1. Escを押して挿入モードを終了します
  2. :wqと入力してEnterを押して保存して終了します

エントリが追加されたことを確認します。

crontab -l

新しく追加された行が表示されるはずです。

次に、毎日午前 8 時に実行される別のcronジョブを追加しましょう。このジョブは、ホームディレクトリのディスク使用量を~/disk_usage.logに記録します。

編集のためにcrontabをもう一度開きます。

crontab -e

vim で:

  1. iを押して挿入モードに入ります
  2. 前の行の下に次の行を追加します。
0 8 * * * du -sh ~ >> ~/disk_usage.log
  1. Escを押して挿入モードを終了します
  2. :wqと入力してEnterを押して保存して終了します

両方のエントリが存在することを確認します。

crontab -l

これで、両方のcronジョブがリストされているはずです。

cronは、一般的なスケジュールを簡素化できる特別な文字列もサポートしています。これらには、@reboot@yearly@annually@monthly@weekly@daily@midnight、および@hourlyが含まれます。たとえば、@hourly0 * * * *と同等です。

毎時実行され、システムの稼働時間を~/uptime_log.txtに記録するジョブを追加しましょう。

編集のためにcrontabを開きます。

crontab -e

vim で:

  1. iを押して挿入モードに入ります
  2. 次の行を追加します。
@hourly uptime >> ~/uptime_log.txt
  1. Escを押して挿入モードを終了します
  2. :wqと入力してEnterを押して保存して終了します

3 つのすべてのエントリを確認します。

crontab -l

これで、3 つのすべてのcronジョブが表示されるはずです。

これらのジョブの効果を示すために、しばらく待ちます。ジョブは異なる間隔でスケジュールされているため、すべてがすぐに実行されるわけではありませんが、設定を確認できます。

*/2ジョブが少なくとも 1 回実行されるように、少なくとも 3 分待ちます。

~/cron_messages.txtファイルを確認します。

cat ~/cron_messages.txt

少なくとも 1 つの"Hello from cron!"メッセージが表示されるはずです。

Hello from cron!

~/disk_usage.logおよび~/uptime_log.txtファイルは、現在の時刻によってはまだ作成されていない可能性があります。これらはそれぞれ毎日および毎時実行するようにスケジュールされているためです。重要なのは、それらのエントリがcrontabに正しく構成されていることです。

これで、ユーザーcrontab 管理ステップが完了しました。すべての cron ジョブは、コンテナが破棄されるまで実行を続けます。

cron ディレクトリで定期的なシステムジョブをスケジュールする

このステップでは、cronディレクトリを使用して、定期的なシステム全体のタスクをスケジュールする方法を学びます。ユーザー固有のユーザーcrontabエントリとは異なり、システムcronジョブは root ユーザーによって管理され、システム全体に影響を与えます。これらは通常、システムメンテナンス、ログローテーション、およびその他の管理タスクに使用されます。

システム全体の cron ジョブ構成を探索するために、ローカルシステムで引き続き作業します。

システム全体のcronジョブは、/etc/crontabで定義されるか、特定のディレクトリにスクリプトを配置することによって定義されます。

  • /etc/cron.hourly/: このディレクトリ内のスクリプトは 1 時間に 1 回実行されます。
  • /etc/cron.daily/: このディレクトリ内のスクリプトは 1 日に 1 回実行されます。
  • /etc/cron.weekly/: このディレクトリ内のスクリプトは 1 週間に 1 回実行されます。
  • /etc/cron.monthly/: このディレクトリ内のスクリプトは 1 か月に 1 回実行されます。

これらのディレクトリは、run-partsユーティリティによって処理され、その中のすべての実行可能ファイルが実行されます。

システムcronジョブを管理するには、root 権限が必要です。labex ユーザーには sudo アクセス権があるため、必要なコマンドにsudoを使用できます。

システムログにメッセージを記録する簡単なスクリプトを作成しましょう。このスクリプトを/etc/cron.hourly/に配置して、1 時間ごとに実行されるようにします。

まず、スクリプトファイル/etc/cron.hourly/my_hourly_scriptを作成します。

sudo nano /etc/cron.hourly/my_hourly_script

ファイルに次の内容を追加します。

#!/bin/bash
logger "Hourly cron job executed at $(date)"

エディタを保存して終了します(nanoCtrl+oEnterCtrl+x)。

次に、スクリプトを実行可能にする必要があります。実行権限がないと、run-partsはそれを無視します。

sudo chmod +x /etc/cron.hourly/my_hourly_script

次に、スクリプトが実行可能であることを確認しましょう。

ls -l /etc/cron.hourly/my_hourly_script

権限にxが表示されるはずです。たとえば、-rwxr-xr-xです。

cron.hourlyジョブは 1 時間に 1 回実行されるため、この実験では、その実行を確認するために 1 時間待つことはできません。ただし、時間ごとのディレクトリのrun-partsコマンドを手動でトリガーして、その実行をシミュレートできます。

sudo run-parts /etc/cron.hourly/

このコマンドは、/etc/cron.hourly/にあるすべての実行可能スクリプトを実行します。作成したスクリプトは、loggerコマンドを使用してメッセージをシステムログに書き込みます。このコンテナ環境ではログ出力を簡単に確認することはできませんが、重要な学習目標は、cron ディレクトリでスクリプトを作成および管理する方法を理解することです。

実際の RHEL システムでは、journalctlまたは/var/log/messagesを使用してシステムログを確認し、スクリプトが正常に実行されたことを確認できます。

これで、システム cron ジョブ管理ステップが完了しました。スクリプトはそのまま残り、実際のシステム環境では 1 時間ごとに実行されます。

定期タスクに systemd タイマーを設定する

このステップでは、Linux システムでタスクをスケジュールするためのcronの最新の代替手段であるsystemdタイマーについて学びます。systemdタイマーは、より柔軟性があり、systemdエコシステムとのより良い統合を提供します。systemctlコマンドは通常、systemdユニットを管理するために使用されますが、Docker コンテナ環境のため、タイマーとサービスユニットファイルを直接作成して検証することに焦点を当てます。

systemdタイマーは、systemdサービスユニットと連携して動作します。タイマーユニット(.timerファイル)は、タスクを実行するタイミングを定義し、サービスユニット(.serviceファイル)は、実行するタスクを定義します。

systemd タイマーの設定を探索するために、ローカルシステムで引き続き作業します。

システムディレクトリにsystemdユニットファイルを作成するには、root 権限が必要です。labex ユーザーには sudo アクセス権があるため、必要なコマンドにsudoを使用できます。

ファイルにメッセージを記録するシンプルなサービスを作成しましょう。このサービスユニットファイルを、カスタムサービスユニットが通常保存される/etc/systemd/system/に配置します。

サービスユニットファイル/etc/systemd/system/my-custom-task.serviceを作成します。

sudo nano /etc/systemd/system/my-custom-task.service

ファイルに次の内容を追加します。

[Unit]
Description=My Custom Scheduled Task

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'echo "My custom task executed at $(date)" >> /var/log/my-custom-task.log'

エディタを保存して終了します(nanoCtrl+oEnterCtrl+x)。

次に、タイマーユニットファイル/etc/systemd/system/my-custom-task.timerを作成します。このタイマーは、5 分ごとにサービスをアクティブ化します。

sudo nano /etc/systemd/system/my-custom-task.timer

ファイルに次の内容を追加します。

[Unit]
Description=Run My Custom Scheduled Task every 5 minutes

[Timer]
OnCalendar=*:0/5
Persistent=true

[Install]
WantedBy=timers.target

エディタを保存して終了します。

OnCalendarの説明:

  • *:0/5は「5 分ごと」を意味します。
    • *は年、月、日、時(任意の値)を表します。
    • 0/5は分を表し、0 分から始めて 5 分ごと(0、5、10、...、55)を意味します。

一般的なsystemd環境では、新しいユニットファイルをsystemdに認識させるためにsystemctl daemon-reloadを実行し、次にタイマーを開始するためにsystemctl enable --now my-custom-task.timerを実行します。ただし、Docker コンテナの制限により、systemctlは完全に機能していません。

代わりに、ファイルの作成を手動で検証します。コンテナ内のsystemdデーモンは最終的にこれらのファイルを取得する可能性がありますが、この実験設定では、そのタイマーの実行を直接制御または観察することはできません。ここでの主な目的は、これらのファイルを設定する方法を理解することです。

作成したファイルの存在を確認しましょう。

ls -l /etc/systemd/system/my-custom-task.service
ls -l /etc/systemd/system/my-custom-task.timer

両方のファイルが存在することを示す出力が表示されるはずです。

サービスの実行をシミュレートするには、ExecStartで定義されたコマンドを手動で実行できます。

sudo /bin/bash -c 'echo "My custom task executed at $(date)" >> /var/log/my-custom-task.log'

次に、ログファイルを確認して、出力を確認します。

sudo cat /var/log/my-custom-task.log

先ほどログに記録したメッセージが表示されるはずです。

My custom task executed at Tue Jun 10 06:54:40 UTC 2025

これで、systemd タイマー設定ステップが完了しました。サービスとタイマーユニットファイルは、参照のためにそのまま残ります。

systemd-tmpfiles で一時ファイルを管理する

このステップでは、systemd-tmpfilesを使用して一時ファイルとディレクトリを管理する方法を学びます。このユーティリティはsystemdの一部であり、揮発性および一時的なファイルとディレクトリの作成、削除、およびクリーンアップを担当します。これは、/tmp/var/tmp、およびその他の一時的なストレージ場所を管理し、古いファイルが定期的に削除されるようにするために一般的に使用されます。

systemd-tmpfiles の設定を探索するために、ローカルシステムで引き続き作業します。

systemd-tmpfilesを設定するには、root 権限が必要です。labex ユーザーには sudo アクセス権があるため、必要なコマンドにsudoを使用できます。

systemd-tmpfilesは、/etc/tmpfiles.d/および/usr/lib/tmpfiles.d/から設定ファイルを読み取ります。これらのファイルは、ファイルとディレクトリの作成、削除、および管理に関するルールを定義します。

新しい一時ディレクトリを管理するためのカスタム設定ファイルを作成しましょう。/run/my_temp_dirディレクトリを作成し、そこから 1 分より古いファイルをクリーンアップするようにsystemd-tmpfilesを設定します。

設定ファイル/etc/tmpfiles.d/my_temp_dir.confを作成します。

sudo nano /etc/tmpfiles.d/my_temp_dir.conf

ファイルに次の内容を追加します。

d /run/my_temp_dir 0755 labex labex 1m

行の説明:

  • d: このエントリがディレクトリを定義することを指定します。
  • /run/my_temp_dir: ディレクトリへのパス。
  • 0755: ディレクトリのパーミッション。
  • labex labex: ディレクトリの所有者とグループ。
  • 1m: このディレクトリ内のファイルが削除されるまでの期間(1 分)。

エディタを保存して終了します(nanoCtrl+oEnterCtrl+x)。

次に、systemd-tmpfilesにこの設定を適用するように指示しましょう。--createオプションは、ディレクトリが存在しない場合にディレクトリを作成します。

sudo systemd-tmpfiles --create /etc/tmpfiles.d/my_temp_dir.conf

ディレクトリが正しいパーミッションと所有権で作成されたことを確認します。

ls -ld /run/my_temp_dir

次のような出力が表示されるはずです。

drwxr-xr-x 2 labex labex 6 Jun 10 06:55 /run/my_temp_dir

次に、この新しい一時ディレクトリ内にテストファイルを作成しましょう。

sudo touch /run/my_temp_dir/test_file.txt

ファイルが存在することを確認します。

ls -l /run/my_temp_dir/test_file.txt

次に、設定に従ってファイルが「古い」状態になるまで 1 分以上待つ必要があります。少なくとも 70 秒(1 分 10 秒)待ちます。

1 分以上待った後、systemd-tmpfiles--cleanオプションで手動で実行して、設定に基づいてクリーンアッププロセスをトリガーします。

sudo systemd-tmpfiles --clean /etc/tmpfiles.d/my_temp_dir.conf

最後に、test_file.txtが削除されたかどうかを確認します。

ls -l /run/my_temp_dir/test_file.txt

「そのようなファイルまたはディレクトリはありません」というエラーが表示されるはずです。これは、systemd-tmpfilesが古いファイルを正常にクリーンアップしたことを示しています。

これで、systemd-tmpfiles 設定ステップが完了しました。設定ファイルと一時ディレクトリは、参照のためにそのまま残ります。

まとめ

この実験では、atコマンドを使用して、対話的および非対話的にジョブをスケジュールする方法、atqatキューを表示する方法、およびatrmで保留中のジョブを削除する方法など、1 回限りのタスクをスケジュールおよび管理する方法を学びました。また、crontabを使用して、cron ジョブの編集、リスト表示、削除の方法、および実行時間を指定するための cron 構文を理解することを含め、ユーザー固有の定期的なタスクをスケジュールすることにも習熟しました。さらに、この実験では、スクリプトを標準の cron ディレクトリ(/etc/cron.hourly/etc/cron.dailyなど)に配置してシステム全体の定期的なタスクをスケジュールする方法、および/etc/cron.dでカスタム cron ジョブを作成する方法を示しました。

最後に、systemdタイマーを使用した高度なタスクスケジューリングを探索し、定期的なタスクのサービスユニットとタイマーユニットを作成して有効にする方法、および自動クリーンアップのためにsystemd-tmpfilesを使用して一時ファイルとディレクトリを管理する方法を学びました。この包括的な実験は、単純なワンオフコマンドから複雑な定期的なシステムプロセスまで、RHEL システムにおける多様なタスクスケジューリングのニーズを管理するための実践的な経験を提供しました。