我有一个 LaunchDaemon。当它运行时,它会检查是否安装了 SIMBL。如果没有安装 SIMBL,它会使用 NSTask 在 SIMBL.pkg 上运行 /usr/sbin/installer。
SIMBL 的 postflight 脚本然后尝试运行 launchctl load 命令以立即启动 SIMBL 的 LaunchAgent:
sudo -u "$USER" -- /bin/launchctl load -F -S Aqua -D user "${LAUNCHD_PLIST}"
这失败了,因为我的 LaunchDaemon 的 NSTask 环境没有设置 $USER 。
如果我让我的守护进程使用系统配置框架检测当前用户并使用 setEnvironment 将其传递给 NSTask,launchctl 会在我身上出现错误:
Bug: launchctl.c:2325 (23930):13: (dbfd = open(g_job_overrides_db_path, O_RDONLY | O_EXLOCK | O_CREAT, S_IRUSR | S_IWUSR)) != -1
我意识到,根据定义,守护进程不应该在用户会话中运行。出于同样的原因,Apple 似乎推荐 LaunchAgents 作为 LaunchDaemons 的辅助对象,以完成用户会话工作。有没有办法让这样的代理立即启动并运行?
我将所有 .plist 都放在正确的位置(它们在重新启动后开始运行,下次 launchctl 进行常规加载)所以我的第一个想法就是告诉 launchctl 重新加载。但是所有执行此操作的代码都在 launchctl.c 中注释掉了:
// { "reload", reload_cmd, "Reload configuration files and/or directories" },
...
* In later versions of launchd, I hope to load everything in the first pass,
* then do the Bonjour magic on the jobs that need it, and reload them, but for now,
* I haven't thought through the various complexities of reloading jobs, and therefore
* launchd doesn't have reload support right now.