MacOS で at コマンドを有効化して使ってみる

あるコマンドを予約実行したい場合、すぐ思い付くのは cron (crontab) かと思われる。しかし cron は、ある処理を定期的に繰り返し実行するスケジュール設定になっており、ある処理をある時に1回だけ行いたい場合には使いづらい。

ある処理を1回だけ予約実行したい場合は、at というコマンドを使うと良い。

今回は at コマンドを MacOS Mojave で使ってみる。

目次

at コマンドを有効化する

MacOS で at コマンドを使う際は、どうも最初に at コマンドを有効化する必要があるようだった。

まずは以下のファイルを vi で開く。

$ sudo vi /System/Library/LaunchDaemons/com.apple.atrun.plist

<key>Disabled</key> の次の行に、<true/> と書かれた部分があれば、それを <false/> に書き換える。最初から <false/> であれば問題なし。

続いて以下のコマンドを打つ。

$ sudo launchctl unload -F /System/Library/LaunchDaemons/com.apple.atrun.plist
$ sudo launchctl load -F /System/Library/LaunchDaemons/com.apple.atrun.plist

コレで at コマンドが動作するようになった。

at コマンドを試してみる

at コマンドが動作するか、試しに叩いてみよう。

$ echo 'echo TEST' | at now+10

とコマンドを実行すると、

job 28 at Thu Jun 27 10:49:10 2019

こんな形でジョブがスケジュール登録された反応が返ってくる。この後すぐに atq コマンドを実行してみると、スケジュール登録されている情報が確認できる。

$ atq
28      Thu Jun 27 10:49:00 2019

ジョブは現在時刻から10秒後に実行する設定にしてあるので、余裕をもって2・30秒待ってから再度 atq コマンドを叩くと、今度は何も表示されないと思う。ジョブが実行されてスケジュール一覧から消えたからだ。

実行されたジョブの内容は、MacOS の場合だと、/var/mail/【ユーザ名】 というファイルにログ出力される。正確にはジョブの実行結果をメールする文面が見えているのだが、実行結果ログとして事足りる。

$ tail -f /var/mail/【ユーザ名】

のように叩くと、以下のような内容が表示されるかと思う。

From 【ユーザ名】@【ホスト名】.local  Thu Jun 27 10:52:43 2019
Return-Path: <【ユーザ名】@【ホスト名】.local>
X-Original-To: 【ユーザ名】
Delivered-To: 【ユーザ名】@【ホスト名】.local
Received: by 【ユーザ名】@【ホスト名】.local (Postfix, from userid 501)
        id 1379A9DF000; Thu, 27 Jun 2019 10:52:42 +0900 (JST)
Subject: Output from your job a0001d018d0000
Message-Id: <20190627010000.1379A9DF000@【ホスト名】.local>
Date: Thu, 27 Jun 2019 10:52:42 +0900 (JST)
From: 【ユーザ名】@【ホスト名】.local (Atrun Service)

TEST

こんな感じで実行できていれば OK だ。

at コマンドの叩き方

at コマンドの叩き方はいくつかあるので、代表的なモノを紹介しておこう。

実行日時を指定する

実行日時を指定するには、-t オプションを使うと良い。

$ at -t 1906301720

このように叩くと、「(20) 19年・06月・30日・17時・20分」に実行するよう予約される。

現在時刻より過去の日時を指定した場合は、スケジュール登録されてから順次実行される。at コマンドの発動は若干のタイムラグがあるが、大体1分以内の誤差で動作する感じ。

実行するコマンドを入力する

先程の例では echo 'echo TEST' というコマンドをパイプで at コマンドに渡していたが、コレと同じことは以下のように入力できる。

$ at now+10
# ココで Return キーを押下すると次の行に移動し、コマンドが入力できるようになる
echo TEST
# 実行したいコマンドを入力して Return キーを押下する
# 空行にカーソルが移動したら、Control + D キーを押下する
job 31 at Thu Jun 27 10:58:58 2019
# 以上のようにスケジュール登録できる

キモは Control + D キーだ。コレを知らないと、at コマンドで任意のコマンドを登録する方法が分からないだろう。

コマンドの代わりに実行するファイルを指定する

コマンドを直接入力する代わりに、シェルスクリプトファイルを実行するよう指定できる。

例えば以下のようなシェルスクリプトを用意しておく。

$ echo EXECUTED
$ touch OK.txt

そして次のようにスケジュール登録する。

$ at -t 1906301105 -f ./at-job.sh

スケジュールどおりに実行されると、at-job.sh と同じディレクトリに OK.txt というファイルが生成され、/var/mail/【ユーザ名】 ファイルを確認すると、EXECUTED という文言が記録されているだろう。

登録されているジョブを確認する

登録して実行前のジョブを確認するには、先程紹介した atq コマンドか、at -l コマンドを使う。どちらも表示される内容は同じ。

以上

指定の日時に1度だけコマンドを実行する at。MacOS でも簡単に使えたのでオススメ。