指定した日時にコマンド(スクリプト)を一度だけ実行:atコマンド【Mac】

コンピュータ関連
スポンサーリンク

スクリプトやコマンドなどを「決まった時間、曜日、日付等で繰り返し実行」させるには
cronlaunchd がある。

では指定した日付、時間に「一度(1回)だけ実行」してくれるコマンドは?

それは atコマンド を使えば良いらしい。

スポンサーリンク

事前に指定した日時に繰り返し実行(cron、launchd)

あらかじめ指定した時間に実行させる方法はわりとすぐに見つかります。

前述の cron や launchd がそれ。
ただし「繰り返し」という話が付いて回る。

とは言えオプションの設定でなんとかできるんちゃう?
・・・と色々探してみた結果、残念ながら無理!という結論に至る。

たしかに設定において年を指定すれば1年に一回となるけど・・・それでも繰り返しだしね。

ただlaunchdにおいては LaunchOnlyOnce というキーを設定すれば、
「再起動しない限り」1回だけ実行されるらしい

	<key>LaunchOnlyOnce</key>
	<true/>

が、やっぱり不完全。

だって再起動くらいたまにするもの。

指定日時に一度だけ実行するatコマンド

というわけで表題のatコマンドについて。

実のところ早い段階で「atコマンド」の存在には気づいていた。
ところがAppleのドキュメントを読んでみると

In OS X, you can run a background job on a timed schedule in two ways: launchd jobs and cron jobs. (Older approaches, such as at jobs and periodic jobs are deprecated and should not be used.) This section explains these methods briefly and provides links to manual pages that provide additional details.

Scheduling Timed Jobs

”at jobs や periodic jobs などの古いアプローチは非推奨であり、使うべきではありません”
ときた。

それゆえに atコマンド はデフォルトでは無効になっている。

なので launchd のオプションあたりに何かあるのではないかと考えたのだが・・・結果は前述の通り。

なんでだろう?「1度だけ、1回だけ実行」する方法がすっぽりと抜け落ちているような気がする。
(※ないよね?知ってる人いたら教えてください)

まぁ以前の記事でカレンダーを使った方法を紹介しているので、全くないわけではないのだけれど。

カレンダーイベントの情報を読み取ってコマンド実行(第三弾)【Mac|AppleScript】
実現しようとしているのはネット配信番組の動画を予約録画すること。 そのスケジューラにはMac標準アプリのカレンダーを使用。 今回は「あらかじめ登録したイベント情報(URL)をAppleScriptで読み込む」ように改良してみました。...

ちなみにcronもまた(まだサポートされているものの)非推奨となっているらしく、launchdを使うことを推奨と書いてあった。

スポンサーリンク

atコマンドの使い方(at,atq,atrm)

atコマンドの説明を簡単に。

atrun を有効にする

atrun(at)を使えるようにするにはまず設定を変える必要がある。

atのマニュアルを読んでみると

Note that at is implemented through the launchd(8) daemon periodically invoking atrun(8), which is disabled by default. See atrun(8) for information about enabling atrun.

“at は launchd デーモンが定期的に atrun(デフォルトでは無効)を呼び出すことで実装されていることに注意してください。atrun の有効化についての情報は atrun を参照してください。”

次に atrun の説明を読んでみた結果、

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

と打ち込めば有効化できるようだ。

実際にターミナルから打ち込んで有効化。
これでatコマンドが使えるようになった。

HSでは関係ありませんが、mojave(10.14)からはシステム環境設定のセキュリティとプライバシーで「フルディスクアクセス」にatrunを追加してあげる必要があるようです。

時間指定の仕方

日付の指定などはいくつもの方法があるみたい。

HHMM
HH:MM

midnight, noon, teatime (4pm) などの指定も可能。
また、
now + 30 min
なんてのも大丈夫。

とは言え自分の使いやすいフォーマットを一つ覚えておけば十分かな。

t(小文字ティー)オプションをつけて
例:2020/5/22 19時59分30秒の場合 [[CC]YY]MMDDhhmm[.SS]

$ at -t 202005221959.30 -f ~/test.sh

時間が来たらホームディレクトリにある test.sh を実行します。

た・だ・し、秒数指定までしても正確に時間を守ってくれるわけではなさそうです。

何度かテストしてみましたが、数秒〜数十秒程度前後する模様

えぇ、”前後”するのです。

10秒くらい前に実行されたり、20秒くらい後で実行されたり。
・・・結構いい加減。

qオプションで優先度が設定できるらしいが結果は変わらず。

batchコマンドは負荷がかからないタイミングで実行されるらしいのだけれどatコマンドにその説明はない。
ん〜よくわからんち。

スポンサーリンク

1、ジョブの入れ方「スクリプトファイルを実行」

先ほどの例に挙げたように f(小文字エフ)オプションを使います。

$ at -t 202005250130 -f ~/myjob/job.sh

2020/05/25 01:30 に ~/myjob/job.sh が実行されます。

2、ジョブの入れ方「コマンド実行」

ターミナルから打ち込みます。
まずは時間を指定。

$ at -t 202005250130

リターンを押したら次の行からコマンドを入力。
入力がおわったら ctrl + d で終了します。
入力を終えると直後にジョブ番号と時間が表示されます。

例:指定した時間にsafariが起動します。

$ at -t 202011281705
open /Applications/safari.app
job 42 at Sat Nov 28 17:05:00 2020

jobの確認(atq)

$ atq

と入力すればjobの一覧がリスト表示される。

小文字エル(l)オプションに同じ。

$ at -l

jobの削除(atrm)

atq で表示させたjobの番号を指定して削除する。
例:12と表示されたjobを削除

$ atrm 12

これは小文字アール(r)オプションに同じ。

$ at -r 12

まとめ

スケジューラとして使っていたカレンダー。

このカレンダーイベント、ちょっと心もとないというか・・・信用できない時があるのです。

ちゃんと設定したはずなのに、念のため再度開いてみると反映されていないとか・・・
設定したことを確認したはずなのに実行できていなかったりとか・・・

そんな時は何故かイベント自体が消えていたりする。
手動で削除しない限りはカレンダーに残り続けるはずなのに。

なんか挙動不審。

ということで代替手段を求めて情報の大海をさまよってました。

とりあえず指定した時間(くらい)に1度だけ実行してくれるatコマンドは覚えました。

一応備忘録として記事化。

コメント

タイトルとURLをコピーしました