at コマンド入門 - 一度きりのジョブを予約実行する
この記事で解決できること
atで 一度きりのジョブを予約 する方法が分かるatq/atrmで 予約済みジョブを確認・取り消し できるcronとatの 使い分け がはっきりする
結論(実務の型)
- 1回だけ・指定時刻に実行 →
at - 繰り返し・定期実行 →
cron/ systemd timer - まず
atdが動いているか確認、ジョブ管理はatqとatrmの2つで足りる
前提(対象環境)
- OS: Ubuntu / Debian 系(RHEL 系も基本同じ)
atパッケージとatdデーモンが必要(既定では未インストールのことが多い)
at コマンドとは?
結論:
atは指定した時刻に 一度だけ コマンドを実行する予約ツール。繰り返さない単発処理に向く。
cron が「毎日・毎週」のような繰り返し実行を担うのに対し、at は「今夜23時に1回だけ」「5分後に1回だけ」という 単発のスケジュール実行 を担う。
予約されたジョブは atd(at デーモン)がキューを監視し、時刻が来たら実行する。ログインを切っても、シェルを閉じても予約は残る。
似た用途に batch がある。batch は時刻ではなく システム負荷が下がったタイミング でジョブを実行する。重いバッチ処理を混雑時間帯から外したいときに使う。
at は使える状態か? atd の確認とインストール
結論:
at本体だけでなくatdが起動していないとジョブは実行されない。まず動作状態を確認する。
多くの Ubuntu / Debian 環境では at は初期状態で入っていない。次の手順で導入・確認する。
# インストール(Debian / Ubuntu) $ sudo apt install at # RHEL / CentOS / Rocky の場合 $ sudo dnf install at
デーモンの起動状態を確認する。
$ systemctl status atd
● atd.service - Deferred execution scheduler
Loaded: loaded (/lib/systemd/system/atd.service; enabled; preset: enabled)
Active: active (running) since ...
active (running) でなければ起動・自動起動を有効化する。
$ sudo systemctl enable --now atd
予約したのに実行されない事故の多くは「atd が起動していない」が原因。at でジョブを登録できても、atd が止まっていれば時刻が来ても何も起きない。
どうやってジョブを予約するのか?
結論:
at 時刻を実行し、対話プロンプトにコマンドを入力してCtrl+Dで確定する。スクリプトは-fで渡す。
対話で登録する
$ at now + 5 minutes warning: commands will be executed using /bin/sh at> echo "hello" >> /tmp/at-test.log at> <EOT> job 3 at Fri Jun 5 23:10:00 2026
at> プロンプトでコマンドを入力し、最後に Ctrl+D を押す(表示上は <EOT>)。登録されるとジョブ番号と実行予定時刻が表示される。
ファイルから登録する(推奨)
対話入力はタイプミスに弱い。実務ではスクリプトを -f で渡すほうが安全。
$ at -f /path/to/job.sh 23:00
# ワンライナーをパイプで渡す $ echo 'tar czf /backup/data.tgz /var/www' | at 02:00 tomorrow
予約時の カレントディレクトリ・環境変数・umask は登録した時点の状態が保存 され、実行時に復元される。ただし PATH に依存する書き方は避け、コマンドは絶対パスで書くのが安全。
時刻指定はどう書くのか?
結論:
HH:MM、now + N units、midnight/noon/teatime、日付指定など柔軟に書ける。相対指定が最も実用的。
at の時刻表現は柔軟。代表的なパターンを挙げる。
| 書き方 | 意味 |
|---|---|
at 23:00 |
今日の23時(過ぎていれば翌日) |
at 10:00 AM |
午前10時 |
at now + 30 minutes |
30分後 |
at now + 2 hours |
2時間後 |
at midnight |
今夜0時 |
at noon |
正午 |
at teatime |
16時(ティータイム) |
at 02:00 tomorrow |
明日の2時 |
at 10:00 next week |
来週の同曜日10時 |
at 2026-12-31 23:59 |
日付+時刻を明示 |
# 例: 明日の午前3時にログをローテート $ echo '/usr/local/bin/rotate-logs.sh' | at 3:00 tomorrow
時刻を指定せず過ぎた時刻を書くと、at は 翌日の同時刻 として解釈する。「すぐ実行されるはず」が翌日にずれる事故に注意。確実に近い未来へ入れたいときは now + N minutes が安全。
予約したジョブを確認・取り消すには?
結論: 一覧は
atq、削除はatrm ジョブ番号、中身の確認はat -c ジョブ番号。この3つで管理は足りる。
予約一覧を見る(atq)
$ atq
3 Fri Jun 5 23:10:00 2026 a user 5 Sat Jun 6 02:00:00 2026 a user
左から ジョブ番号 / 実行予定時刻 / キュー名 / 所有者。a は通常キュー、b は batch キューを表す。
ジョブを取り消す(atrm)
$ atrm 3
番号を指定して削除する。複数まとめて消すこともできる。
$ atrm 3 5
中身を確認する(at -c)
実行前に「何が登録されているか」を確認したいときは -c。
$ at -c 5
保存された環境変数の復元処理と、実際に走るコマンド本体が表示される。
atq は at -l、atrm は at -d と同じ。スクリプト内では明示的な atq / atrm のほうが読みやすい。
実行結果はどこに出るのか?
結論: ジョブの標準出力・標準エラーは メール でユーザーに送られる。メールが無い環境では出力が消えるため、ファイルへリダイレクトする。
at で実行したコマンドの出力は、端末ではなく 登録ユーザー宛のローカルメール に届く。mail コマンドや /var/mail/<user> で確認できる。
ただしサーバーに MTA(メール配送)が無い構成では出力が捨てられる。結果を確実に残すには、ジョブ側でリダイレクトする。
$ echo '/usr/local/bin/backup.sh > /var/log/backup.log 2>&1' | at 02:00
「実行されたはずなのに結果が見当たらない」ときは、メールに飛んでいるか、出力先を指定し忘れている可能性が高い。本番ジョブは必ずログファイルへ > ... 2>&1 でリダイレクトする。
cron と at はどう使い分けるのか?
結論: 繰り返すなら
cron/ systemd timer、1回だけならat。「今夜だけ」「メンテ後に1回」のような単発処理はatが最適。
| 用途 | 推奨 |
|---|---|
| 毎日・毎週など定期実行 | cron / systemd timer |
| 指定時刻に1回だけ | at |
| 負荷が下がったら実行 | batch |
| 高信頼な定期ジョブ(ログ・依存管理) | systemd timer |
単発作業を cron に書いて「実行後に消し忘れて翌日も動く」事故は珍しくない。1回限りと分かっているなら at のほうが後始末が要らず安全。
定期ジョブ全般の組み方は cron の基本 と systemd timer と cron の使い分け を参照。
アクセス制御と注意点
結論:
atの利用可否は/etc/at.allowと/etc/at.denyで制御する。at.allowがあればそれが優先される。
/etc/at.allowが存在する場合: 記載されたユーザーのみatを使えるat.allowが無く/etc/at.denyがある場合: 記載ユーザー以外が使える- 両方無い場合: 多くのディストロでは root のみ(ディストロにより挙動差あり)
# 特定ユーザーのみ許可したいとき $ echo 'deploy' | sudo tee -a /etc/at.allow
共有サーバーでは at がジョブ実行の踏み台になり得る。不要なら at.deny で絞るか atd を止める。逆に運用で使うなら at.allow で明示許可する設計が安全。
まとめ
atは 一度きりのジョブを予約 するためのコマンド。繰り返しはcronの担当- 実行には
atdの起動が必須。動かないときはまずデーモン状態を確認 - 時刻は
now + N minutesなどの相対指定が安全。過去時刻は翌日扱いになる - 管理は
atq(一覧)/atrm(削除)/at -c(内容確認)の3つ - 出力はメールに届く。本番ジョブはログへリダイレクトする