caffeinateはmacOS標準搭載のコマンドで、ディスプレイやシステムのスリープを一時的に抑止できる。長時間のビルドやダウンロード中にスリープしてほしくない場合などに使える。オプションは少なく、実際には複数のオプションを組み合わせて使う場面が多いため、まとめて解説する。

基本的な使い方

オプションなしで実行すると、システムのアイドルスリープを防止するアサーション(後述)を作成する。

$ caffeinate

utility(実行したいコマンド)を指定しない場合、アサーションはcaffeinate自身のプロセスが終了するまで持続する。Ctrl + Cなどでプロセスを終了させない限りスリープ抑止が続くため、フォアグラウンドで実行したままにするか、&でバックグラウンド実行してPIDを控えておく。

$ caffeinate &
[1] 12345
$ kill 12345

utilityを引数に指定すると、caffeinateはそのコマンドを子プロセスとして実行し、utilityの実行中だけアサーションを保持する。utilityが終了すると同時にアサーションも解放される。

$ caffeinate make

この例では、makeが実行されている間だけアイドルスリープを防止し、makeが終了すると同時にスリープ抑止も解除される。

オプションでスリープ抑止の種類を指定する

オプションなしの場合、内部的には-iと同じ「システムのアイドルスリープ防止」のアサーションが作成される。caffeinateは指定したオプションに応じて複数の種類のアサーションを同時に作成できる。

オプション抑止する対象
-iシステムのアイドルスリープ(無指定時のデフォルトと同じ)
-dディスプレイのスリープ
-mディスクのアイドルスリープ
-sシステムのスリープ(AC電源接続時のみ有効)
-uユーザーがアクティブであることの宣言

pmset -g assertionsで、実際にどの種類のアサーションが保持されているかを確認できる。例えば-dを指定して実行すると、PreventUserIdleDisplaySleepという名前のアサーションがcaffeinateのプロセスIDで登録される。

$ caffeinate -d -t 5 &
$ pmset -g assertions | grep -A3 "caffeinate command-line tool"
   pid 82430(caffeinate): [0x0004ba2a00059e54] 00:00:01 PreventUserIdleDisplaySleep named: "caffeinate command-line tool"
	Details: caffeinate asserting for 5 secs
	Localized=THE CAFFEINATE TOOL IS PREVENTING SLEEP.
	Timeout will fire in 4 secs Action=TimeoutActionRelease

-mPreventDiskIdle-sPreventSystemSleep-uUserIsActiveという名前のアサーションになる。-sはAC電源接続時のみ有効なオプションで、バッテリー駆動時に指定してもアサーションが効かない。

オプションは組み合わせて指定できる。-dimsのようにまとめて指定すると、対応する複数種類のアサーションが同時に作成される。

$ caffeinate -dims sleep 3 &
$ pmset -g assertions | grep -E "PreventUserIdleDisplaySleep|PreventUserIdleSystemSleep|PreventDiskIdle|PreventSystemSleep"
   PreventDiskIdle                1
   PreventUserIdleDisplaySleep    1
   PreventSystemSleep             1
   PreventUserIdleSystemSleep     1

ビルド中はディスプレイとディスクの両方をスリープさせたくない、といった場面では単一オプションよりもこの組み合わせ指定の方が実用的である。

-uはデフォルトで5秒のタイムアウトを持つ

-uのみを-tなしで実行すると、UserIsActiveアサーションは5秒で自動的に失効する。ただしcaffeinateのプロセス自体は終了せず、再アサートもされないまま存続し続ける点に注意する。

$ caffeinate -u &
[1] 82715
$ sleep 6
$ pmset -g assertions | grep "UserIsActive named: \"caffeinate"
(何も表示されない=アサーションは失効している)
$ ps -p 82715
  PID TTY           TIME CMD
82715 ??         0:00.00 caffeinate -u
(プロセス自体はまだ存在する)

-d/-i/-m/-s-tを指定しない限りタイムアウトせず、プロセスが終了するまでアサーションを持続する。-uだけがデフォルトで短いタイムアウトを持つ仕様である。

-tでタイムアウト秒数を指定する

-tにタイムアウト秒数を指定すると、指定秒数が経過した時点でアサーションを解放してcaffeinate自身も終了する。プレゼン中やちょっとした作業中だけスリープを防ぎたい場合に使える。

$ caffeinate -d -t 3600

この例では、1時間ディスプレイのスリープを防止したのち、caffeinateは自動的に終了する。

utilityを指定した場合、-tの値は無視される。以下の例では-t 100を指定しているが、アサーションはutilityであるsleep 4の実行時間(4秒)に合わせて解放される。

$ caffeinate -d -t 100 sleep 4 &
$ sleep 4
$ pmset -g assertions | grep "PreventUserIdleDisplaySleep"
   PreventUserIdleDisplaySleep    0

-t 100を指定していても、sleep 4終了と同時に4秒でアサーションが解放されている。

-wで指定したプロセスの終了を待つ

-wにPIDを指定すると、そのプロセスが終了するまでアサーションを保持し、終了と同時にcaffeinate自身も終了する。pmset -g assertionsでは、対象PIDへの依存がDetailsに表示される。

$ sleep 6 &
$ echo $!
82897
$ caffeinate -w 82897 &
$ pmset -g assertions | grep -A2 "caffeinate command-line tool"
   pid 82898(caffeinate): [0x0004ba8600019e60] 00:00:01 PreventUserIdleSystemSleep named: "caffeinate command-line tool"
	Details: caffeinate asserting on behalf of Process ID 82897
	Created for PID: 82897.

すでに実行が長引いているプロセス(自分では止められないビルドツールなど)が終わるまでスリープを防ぎたい場合に使える。

utilityを指定した場合、-wの値は無視される。以下の例のように、-wに別プロセス(10秒間実行されるsleep 10)のPIDを渡しつつutilityとしてsleep 2を指定すると、caffeinate-wで指定したプロセスの終了を待たず、utilityであるsleep 2の終了と同時に終了する。

$ sleep 10 &
$ echo $!
83073
$ caffeinate -w 83073 sleep 2 &
$ sleep 2
$ jobs
(caffeinateはすでに終了している。sleep 10はまだ実行中)

参考

CAFFEINATE Command: Prevent macOS from sleeping