无法在 Yosemite 中使用 launchctl 启动守护进程

无法在 Yosemite 中使用 launchctl 启动守护进程

我有一个 launchd 守护进程,~/Library/LaunchAgents它在 Mavericks 中运行良好。但它无法在 Yosemite 公开测试版中启动。守护进程 plist 如下(我的用户名是darksairUID 501)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>org.darksair.retrmail</string>
    <key>ProgramArguments</key>
    <array>
      <string>/Users/darksair/bin/retrmail.py</string>
    </array>
    <key>KeepAlive</key>
    <false/>
    <key>StartInterval</key>
    <integer>300</integer>
    <key>LaunchOnlyOnce</key>
    <false/>
    <key>UserName</key>
    <string>darksair</string>
    <key>ProcessType</key>
    <string>Standard</string>
    <key>EnvironmentVariables</key>
    <dict>
      <key>PATH</key>
      <string>/Users/darksair/Python/bin:/Users/darksair/Python3/bin:/Users/darksair/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
    </dict>
    <key>StandardOutPath</key>
    <string>/Users/darksair/logs/retrmail.log</string>
    <key>StandardErrorPath</key>
    <string>/Users/darksair/logs/retrmail.log</string>
  </dict>
</plist>

基本上它应该~/bin/retrmail.py每 5 分钟运行一次。

我注意到 Yosemite 中的 launchd 已升级到 2.0,并且 launchctl 有新命令。我试过

sudo launchctl kickstart user/501/org.darksair.retrmail

它说

Could not find service "org.darksair.retrmail" in domain for uid: 501

我也尝试过老派

sudo launchctl load ~/Library/LaunchAgents/retrmail.plist

它说

/Users/darksair/Library/LaunchAgents/retrmail.plist: Path had bad ownership/permissions

该文件归我和员工组所有。我尝试了权限 644 和 600,但出现同样的错误。

那么有人知道如何在 Yosemite 中正确启动 launchd 守护进程吗?


更新:看来我的启动代理文件必须归root:wheel。在我 chown 之后,我尝试

sudo launchctl load ~/Library/LaunchAgents/retrmail.plist

并且没有发出任何错误。而且我思考我的守护进程运行正常。我将这个问题保留开放性,因为我记得 launchd 文档明确指出,启动代理文件可以由运行守护进程的用户可以拥有。


更新 2:不,它没有正常运行。它只运行了一次,但没有再运行,就像它被卸载了一样。


更新 3:我升级到了 Yosemite 公测版 3,并将我的代理更改为此

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>org.darksair.retrmail</string>
    <key>ProgramArguments</key>
    <array>
      <string>/Users/darksair/bin/retrmail.py</string>
    </array>
    <key>StartInterval</key>
    <integer>300</integer>
    <key>UserName</key>
    <string>darksair</string>
    <key>EnvironmentVariables</key>
    <dict>
      <key>PATH</key>
      <string>/Users/darksair/Python/bin:/Users/darksair/Python3/bin:/Users/darksair/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
    </dict>
    <key>StandardOutPath</key>
    <string>/Users/darksair/logs/retrmail.log</string>
    <key>StandardErrorPath</key>
    <string>/Users/darksair/logs/retrmail.log</string>
  </dict>
</plist>

我重新加载了这个代理,我认为它现在工作正常。我仍然没有回答这个问题,因为我不知道我之前的 plist 有什么问题。


总之,我发现我必须将 plist 的所有者更改为root:wheel才能加载它。

答案1

man launchctl

请注意,每个用户的配置文件 (LaunchAgents) 必须由 root 拥有(如果它们位于 /Library/LaunchAgents)或加载它们的用户拥有(如果它们位于 $HOME/Library/LaunchAgents)。所有系统范围的守护进程 (LaunchDaemons) 都必须由 root 拥有。配置文件必须禁止组和全局写入。这些限制是出于安全原因而制定的,因为允许对 launchd 配置文件进行写入允许指定将启动哪个可执行文件。

修复是

sudo chmod 600 /Library/LaunchDaemons/x.plist
sudo chown root /Library/LaunchDaemons/x.plist

答案2

奇怪的是,使用sudo是你的问题。使用sudo,你就不再是你自己了,所以你不是你自己文件的所有者。删除sudo,重复该命令,它应该可以正常加载。抱歉,我对此采取了哲学态度。

答案3

找到解决方案。

在这种情况下,正确的命令是

launchctl bootstrap gui/501 ~/Library/LaunchAgents/retrmail.plist

卸下行李,

launchctl bootout gui/501 ~/Library/LaunchAgents/retrmail.plist

虽然不知道为什么launchctl load需要 root,但无论如何,加载/卸载已被弃用。

答案4

这是一个愚蠢的想法。

升级到 Yosemite 后,我也遇到了同样的错误。我错误地认为这意味着 .plist 文件的所有权/权限不正确,但事实上,由于某种原因,我在 plist 中引用的二进制文件(在我的情况下是 cassandra)丢失了可执行位。

chmod +x'ing 修复了这个问题。

这可能不是你的问题,但值得一试:)

相关内容