sudo pmset -a disksleep 0 を実行/Volumes/Home/.keepalive を作成dd if=/dev/zero of=/Volumes/Home/.keepalive count=1 bs=4096#!/bin/bash #dd if=/Volumes/Home/.keepalive of=/dev/null bs=4k count=1 2>/dev/null /usr/bin/head -c 1 /Volumes/Home/.keepalive >/dev/null 2>&1 || true exit 0
この条件下でThunderbolt NVMe 上に置いた keepalive スクリプトを LaunchAgent で定期実行しようとしたところ、
という状況が発生した。
LaunchAgent(launchd)は「実行ファイルの実体がどこにあるか」を安全性判定に使う。
つまり:
ここで重要なのは
という点。
launchd がチェックするのは「実行ファイルの場所」だけであり、スクリプト内部で外付け NVMe を読むことは sandbox の対象外。
よって、
これが launchd の sandbox を完全に回避する唯一の方法。
スクリプトを使わず、LaunchAgent から 直接 /usr/bin/head を呼ぶ。 /usr/bin/head は内蔵 SSD にあるため、launchd が安全と判断する。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.keepnvmeawake</string> <key>ProgramArguments</key> <array> <string>/usr/bin/head</string> <string>-c</string> <string>1</string> <string>/Volumes/Home/.keepalive</string> </array> <key>StartInterval</key> <integer>60</integer> <key>RunAtLoad</key> <true/> </dict> </plist>
$ launchctl unload ~/Library/LaunchAgents/com.keepnvmeawake.plist $ launchctl load ~/Library/LaunchAgents/com.keepnvmeawake.plist $ launchctl list | grep keepnvmeawake
exit code = 1 になることがあるが、これは launchd が「即終了ジョブ」を失敗扱いにする仕様であり、Thunderbolt NVMe の keepalive には影響しない。
# sudo fs_usage -f filesystem | grep .keepalive
1分ごとに以下のような I/O が出ていれば 完全に成功:
read /Volumes/Home/.keepalive
launchd は「ジョブの最低実行時間」を内部的に持っており、head のような 即終了ジョブは「失敗扱い(exit 1)」になる。
これは 正常挙動であり、keepalive の動作には影響しない。