如何修复launchctl的“Bootstrap failed: 5: Input/output error”错误?
我写了一个shell脚本,希望在每次登录我的MacBook时运行,并且我正在尝试通过launchd来执行它。
我的脚本不是一个持久的守护进程,它应该向一个文件写入一些文本,然后在下次登录前结束。
这是我为它创建的plist,它被 plutil -lint 认为看起来没问题:
<?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.example.test</string>
<key>Program</key>
<string>/Users/Tom/Desktop/tomtest.sh</string>
<key>KeepAlive</key>
<false/>
<key>OnDemand</key>
<false/>
<key>LaunchOnlyOnce</key>
<false/>
<key>StandardOutPath</key>
<string>/Users/Tom/Desktop/tomtest.log</string>
<key>StandardErrorPath</key>
<string>/Users/Tom/Desktop/tomtest.log</string>
<key>Debug</key>
<true/>
</dict>
</plist>
我把它复制到 ~/Library/LaunchAgents/com.example.test.plist,并执行 sudo chown 将它交给 root:wheel。不久之后,我收到一个系统通知,告知我这项新服务;我没有把文字截取下来在这里分享,但看起来很正常(也就是一个好兆头)。而且,当我打开System Settings > General > Login Items & Extensions时,我看到了我的脚本:

以下是shell脚本 tomtest.sh 的全部内容:
#!/bin/sh
echo "I ran" > /Users/Tom/Desktop/tomtest.log
exit 0
尽管注销再登录,日志文件甚至都不存在。所以我手动创建了它(touch),并重新尝试了一下,但仍然没有效果。
当我从CLI手动运行脚本时,它会按预期向日志文件写入文本。
我一直在尝试用 launchctl 调试/修复这个问题,但我总是遇到这个错误:
~ $ launchctl bootstrap gui/501 com.example.test
Bootstrap failed: 5: Input/output error
Try re-running the command as root for richer errors.
~ $ sudo launchctl bootstrap gui/501 com.example.test
Password:
Bootstrap failed: 5: Input/output error
以下是 launchctl print gui/501 的相关输出:
disabled services = {
"com.apple.ManagedClientAgent.enrollagent" => disabled
"com.example.OLDtest" => enabled
"com.apple.Siri.agent" => disabled
"com.apple.FolderActionsDispatcher" => enabled
"com.apple.appleseed.seedusaged.postinstall" => disabled
"com.apple.ScriptMenuApp" => disabled
}
我的 com.example 条目在那里,但(1)它在“禁用”块中混淆地被列为“启用”,(2)它有一个旧名称。旧名称来自plist文件的前一个版本,该版本在名称上有拼写错误,但那个版本的服务也从未工作过。我从未看到新版本出现,尽管有不同的文件名和Label。com.example 在大约2000行输出的其他地方都没有出现。
当我运行 launchctl load ~/Library/LaunchAgents/com.example.test 时,没有输出也没有错误,但日志文件仍然是空的。
为什么这么简单的程序也会出现 "Bootstrap failed: 5: Input/output error"?
如果我这里确实存在X/Y问题:我的真实目标不是写日志文件;我写了一个zsh脚本,每天为我生成新的桌面壁纸,而我真正想运行的脚本会生成PNG文件,然后使用 osascript 实际更换桌面壁纸。它在从命令行运行时可以工作。
因此,我的目标不是启动一个持续的服务,比如数据库服务器。我希望macOS在我每次登录时运行我的脚本,可能每天多次,每次大约需要2 秒钟,然后 exit 0。我的研究表明launchd是实现这一点的最佳工具,但我也愿意接受同样 不可见 的其他方案 —— 我不会接受“登录时打开”,因为它会打开Terminal应用来执行我的脚本。
我是这台机器的唯一用户。
搭载macOS Sequoia 15.5的 M4 MacBook Air
解决方案
你试过:
launchctl unload gui/501
再加载一次?