そんな場面に刺さるのが at コマンドです。
at は「指定した時刻に1回だけコマンドを実行する」ためのジョブスケジューラーです。crontab のように繰り返し実行する設定は不要で、実行が終わればジョブは自動的に消えます。
この記事では、at コマンドの基本的な使い方から、ジョブの確認・削除、crontab・systemd timer との使い分けまでを RHEL 9.4 / Ubuntu 24.04 LTS で動作確認した内容をもとに解説します。
この記事のポイント
・at コマンドは「1回だけ・指定時刻に」ジョブを実行するワンショットスケジューラー
・at -l(atq)でキュー確認、atrm でジョブ削除ができる
・crontab は繰り返し実行、at はワンショット、systemd timer は高機能な1回実行に使い分ける
・atd サービスが起動していないと at は動かない——まず systemctl status atd で確認する
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
atコマンドとは|ワンショットスケジューラーの基本
at は「指定した将来の時刻に、コマンドを1回だけ実行する」ジョブスケジューラーです。1960年代から UNIX に存在する歴史的なコマンドで、現在でも Linux の実務現場で広く使われています。crontab が「毎日0時に実行する」「毎時15分に実行する」という繰り返し実行向けなのに対し、at は「今夜23:00に1回だけ実行したい」というワンショット実行に特化しています。
at の仕組みを簡単に整理するとこうなります。
・atd:at ジョブを管理するデーモン。常駐して時刻になったらジョブを起動する
・at:ジョブをキューに登録するコマンド
・atq(at -l):キューに溜まっているジョブを一覧表示する
・atrm(at -d):キューからジョブを削除する
・batch:システム負荷が低いタイミングで実行する at の亜種
atコマンドのインストールと事前確認
1. atd サービスの状態確認
at コマンドが動くためには atd デーモンが起動している必要があります。まず状態を確認してください。# systemd 環境での確認(RHEL 9 / Ubuntu 24.04) $ systemctl status atd # 出力例(起動済みの場合) * atd.service - Deferred execution scheduler Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; preset: enabled) Active: active (running) since Thu 2026-05-22 09:00:00 JST; 2h 10min ago Main PID: 1023 (atd)
Active: active (running) になっていれば問題ありません。停止している場合は以下で起動します。# atd の起動と自動起動設定 $ sudo systemctl start atd $ sudo systemctl enable atd
2. at コマンドのインストール
最小インストール環境では at が入っていないことがあります。# RHEL 9 / AlmaLinux 9 / Rocky Linux 9 $ sudo dnf install at -y # Ubuntu 24.04 / Debian 12 $ sudo apt install at -y
atコマンドの基本的な使い方
1. 時刻を指定してジョブを登録する
at コマンドの基本構文は次のとおりです。# 基本構文 $ at [時刻指定] # 例:今夜23:00 に実行 $ at 23:00 at> echo "ジョブ完了" >> /tmp/at-test.log at>
← Ctrl+D で入力終了
# 登録後のメッセージ例 warning: commands will be executed using /bin/sh job 3 at Thu May 22 23:00:00 2026
2. 時刻指定のバリエーション
at の時刻指定は非常に柔軟です。# 今夜11時(24時間表記) $ at 23:00 # 明日の午前2時 $ at 02:00 tomorrow # 3時間後 $ at now + 3 hours # 30分後 $ at now + 30 minutes # 特定日時(2026年5月25日 午前1時) $ at 01:00 05/25/2026 # 今夜(midnight = 深夜0時) $ at midnight # 正午 $ at noon # teatime(午後4時 = 16:00) $ at teatime
3. ヒアドキュメントでまとめてジョブを登録する
複数のコマンドをまとめて登録するには、ヒアドキュメントを使う方法が便利です。対話形式より確実で、シェルスクリプトからも呼び出しやすくなります。# ヒアドキュメントを使ったまとめ登録 $ at 23:30 <<'EOF' /usr/local/bin/backup.sh /usr/local/bin/cleanup.sh echo "$(date) バックアップ完了" >> /var/log/at-jobs.log EOF
4. スクリプトファイルを直接指定する
# -f オプションでファイルを指定 $ at -f /usr/local/bin/maintenance.sh 02:00 tomorrow # 実行確認 warning: commands will be executed using /bin/sh job 5 at Fri May 23 02:00:00 2026
ジョブの確認・削除
1. キューに登録済みのジョブを確認する(atq / at -l)
$ atq # または $ at -l # 出力例 3 Thu May 22 23:00:00 2026 a tomohiro 5 Fri May 23 02:00:00 2026 a tomohiro
・左端の数字:ジョブ番号
・日時:実行予定の時刻
・a:キューの種別(a = at、b = batch)
・右端:登録したユーザー名
2. ジョブの内容を確認する(at -c)
# ジョブ番号を指定して内容を表示 $ at -c 3 # 出力例(環境変数の設定と実行コマンドが表示される) #!/bin/sh # atrun uid=1000 gid=1000 # mail tomohiro 0 umask 22 ... echo "ジョブ完了" >> /tmp/at-test.log
3. ジョブを削除する(atrm / at -d)
# ジョブ番号を指定して削除 $ atrm 3 # または $ at -d 3 # 削除確認 $ atq 5 Fri May 23 02:00:00 2026 a tomohiro # ジョブ番号3が消えていることを確認
実務でよく使うatコマンドの活用パターン
1. メンテナンス作業を深夜に予約する
本番サーバーのメンテナンスを業務時間外に自動実行する典型的なパターンです。# 明日の午前2時にデータベースのダンプを取る $ at 02:00 tomorrow <<'EOF' /usr/bin/mysqldump -u backup -pP@ssw0rd mydb > /var/backup/db_$(date +%Y%m%d).sql gzip /var/backup/db_$(date +%Y%m%d).sql echo "$(date) DBダンプ完了" >> /var/log/at-maintenance.log EOF
2. 作業終了後の後片付けを予約する
作業中に「1時間後にテスト用のファイルを消す」という予約を入れておくと、消し忘れを防げます。# 2時間後に一時ファイルを削除 $ at now + 2 hours <<'EOF' rm -rf /tmp/test-deploy-20260522/ echo "$(date) 一時ファイル削除完了" >> /var/log/cleanup.log EOF # 登録確認 $ atq 7 Thu May 22 14:30:00 2026 a tomohiro
3. サービスの再起動を非同期に予約する
SSH セッションを維持したまま、少し先の時刻にサービスを再起動したいときに使えます。# 5分後に Apache を再起動(sudo 権限が必要な場合はrootで実行) $ sudo at now + 5 minutes <<'EOF' systemctl restart httpd echo "$(date) httpd 再起動完了" >> /var/log/at-ops.log EOF
4. ジョブ完了を自動でメール通知する
デフォルトでは、at ジョブに標準出力がある場合、実行ユーザーにメールで通知が届きます。ローカルのメール環境が整っている場合は活用できますが、メールデーモンが未設定の環境では代わりにログファイルへの書き出しを使ってください。# メール通知を使いたい場合(ローカルmail設定済みの環境) $ at 23:00 <<'EOF' /usr/local/bin/backup.sh 2>&1 | mail -s "バックアップ完了" admin@example.com EOF # メール非使用で、ログファイルに出力する場合(推奨) $ at 23:00 <<'EOF' /usr/local/bin/backup.sh >> /var/log/at-backup.log 2>&1 EOF
at・crontab・systemd timerの使い分け
| やりたいこと | 推奨ツール | 理由 |
|---|---|---|
| 毎日・毎週・毎時など繰り返す | crontab -e |
繰り返し実行が得意。設定が一覧で管理しやすい |
| 1回だけ指定時刻に実行 | at 時刻 |
実行後に自動削除されるワンショット向き |
| システム負荷が低いタイミングに実行 | batch |
CPU 負荷が低下するまで待機してから実行する |
| 1回実行+依存関係や精密な実行制御が必要 | systemd timer(OnCalendar) | ジャーナルログ連携・失敗時の再実行などが設定できる |
| SSH 切断後も継続するバックグラウンド処理 | nohup または screen |
実行開始が即時で良い場合はこちら |
アクセス制御|at.allow と at.deny の使い方
at コマンドには、実行を許可・拒否するユーザーを制御する仕組みがあります。# /etc/at.allow(このファイルがある場合、記載されたユーザーのみ実行可能) $ cat /etc/at.allow tomohiro admin # /etc/at.deny(このファイルがある場合、記載されたユーザーは実行不可) $ cat /etc/at.deny testuser
・/etc/at.allow が存在する場合:記載されたユーザーのみ at を使用できる(at.deny は無視)
・/etc/at.allow が存在しない場合:/etc/at.deny に記載されたユーザーは使用不可、それ以外は使用可
・両方存在しない場合:root のみ使用可能
トラブルシュート|atコマンドで詰まったら
「Can't open /var/run/atd.pid to signal atd. No atd running?」が出る
atd が起動していない状態で at ジョブを登録しようとした時のエラーです。# atd の起動確認 $ systemctl status atd # 停止していたら起動する $ sudo systemctl start atd $ sudo systemctl enable atd
ジョブが実行されたはずなのに何も起きていない
at ジョブはコマンド実行時の環境変数を完全に引き継がないことがあります。特に PATH が異なることが多く、フルパスでコマンドを指定するか、スクリプト内で明示的に PATH を設定してください。# NG: コマンドのフルパスを使っていない場合(PATHが通らず失敗することがある) $ at 23:00 <<'EOF' backup.sh EOF # OK: フルパスを指定する $ at 23:00 <<'EOF' PATH=/usr/local/bin:/usr/bin:/bin /usr/local/bin/backup.sh EOF
「You do not have permission to use at.」が出る
at.allow に自分のユーザー名が含まれていないか、at.deny に含まれている場合に出るエラーです。# at.allow と at.deny の確認 $ cat /etc/at.allow 2>/dev/null || echo "at.allow は存在しない" $ cat /etc/at.deny 2>/dev/null || echo "at.deny は存在しない" # root で /etc/at.allow にユーザーを追加 $ echo "tomohiro" | sudo tee -a /etc/at.allow
at ジョブでシステムコマンドが動かない
sudo コマンドは at ジョブ内では tty がないため、通常の sudo が動きません。root ユーザーで at コマンドを実行するか、NOPASSWD 設定の sudoers を使ってください。# 方法1: root で at コマンドを実行する $ sudo at 02:00 <<'EOF' systemctl restart httpd EOF # 方法2: sudoers に NOPASSWD を設定する(/etc/sudoers.d/at-jobs) tomohiro ALL=(root) NOPASSWD: /usr/bin/systemctl restart httpd
本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| 23:00 にジョブを登録する | at 23:00 |
| 3時間後に実行する | at now + 3 hours |
| スクリプトファイルを指定して登録 | at -f /path/to/script.sh 02:00 |
| 登録済みのジョブ一覧を確認する | atq または at -l |
| ジョブの内容を確認する | at -c ジョブ番号 |
| ジョブを削除する | atrm ジョブ番号 または at -d ジョブ番号 |
| atd の起動状態を確認する | systemctl status atd |
| システム負荷が低い時に実行する | batch |
at ジョブが期待どおりに動いているかどうか確認する際は、ジョブ内でログファイルへの書き出しを仕込んでおくと、あとから実行の痕跡を追いやすくなります。ポート確認やプロセス監視と組み合わせて、ジョブ実行前後のサーバー状態を記録しておくのもおすすめです。
Linux無料マニュアルを受け取る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 前のページへ:systemd timerでcronジョブを置き換える方法|.timerユニットの作り方と実践例
- この記事の属するカテゴリ:Linuxtips・シェルスクリプトへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます