无法在 Mac OS X 中成功运行 launchd plist

无法在 Mac OS X 中成功运行 launchd plist

我正在使用 Mac OS X 10.10.5 (Yosemite) 并学习使用启动(启动守护进程)自动运行一些脚本。为了简单起见,我决定使用shell只包含echo命令的脚本。

内容hello.sh

#! /bin/sh
echo "hello"

我也已运行chmod a+x hello.sh使其可执行,当我手动运行脚本时它运行良好。

~/Library/LaunchAgents/com.yang.hello.plist

<?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.yang.hello</string>
        <key>Program</key>
        <string>/Users/yangyy/hello.sh</string>
        <key>RunAtLoad</key>
        <true/>
    </dict>
</plist>

我跑完之后:

launchctl load -w ~/Library/LaunchAgents/com.yang.hello.plist

没有出现任何错误消息,如果我运行此命令:

launchctl list | grep "com.yang.hello"

我得到的答复是:

-   78  com.yang.hello.plist

看起来正数表示退出代码并且程序实际上并没有运行。

此外,当我尝试launchctl start ~/Library/LaunchAgents/com.yang.hello.plist运行该程序时,我发现一些奇怪的事情,但是当我使用此命令时,它返回错误并且没有错误消息。

怎么了?

答案1

我不知道退出状态 78 是什么意思,但我并不指望这个脚本在作为启动代理运行时会做任何可检测到的事情,因为它的输出没有指向任何地方。当您从终端运行它时,它的输出将附加到该终端窗口,因此“hello”会出现在那里。但 launchd 与终端(或任何其他相关输出目标)没有任何连接,因此“hello”会被丢弃。如果您想检查它是否正在运行,您可以通过将这些键添加到 .plist(然后卸载并重新加载它)将其输出(标准输出和错误输出)定向到文件:

<key>StandardOutPath</key>
<string>/Users/yangyy/hello-output.txt</string>
<key>StandardErrorPath</key>
<string>/Users/yangyy/hello-errors.txt</string>

现在,launchd 甚至在启动脚本时也可能遇到其他问题。要查看 launchd 本身是否报告了任何问题,请查看系统日志文件(tail -f /var/log/system.log或运行 /Applications/Utilities/Console.app),然后尝试卸载并重新加载代理,看看日志中是否出现任何相关内容。

答案2

然后,您看到的数字launchctl list就是守护进程退出时发出的状态代码。

因此,好消息是该进程已经运行。

状态 78 是一个通用退出代码,因此坏消息是它没有告诉我们太多信息。

虽然无法帮助您解决确切的问题,但或许可以让您了解正在发生的事情。

答案3

对于我来说,此错误是由于我指定了某个权限问题而导致的,StandardOutPathStandardErrPath该权限问题的最终文件夹(相同)并不存在。加载 plist 确实创建了该文件夹,但没有授予我的用户任何权限。我进行了 chmod 操作,但仍然收到 78 错误代码,并且任何日志文件都没有记录任何内容。我也没有在 Console.app 中看到任何错误。

我通过卸载 plist、删除自动创建的文件夹、手动重新创建文件夹,然后重新加载 plist 解决了该问题。守护进程现在运行正常,日志也按预期写入。

答案4

奇怪的是,我通过对 mrwnt10 的解决方案进行逆运算解决了这个问题:https://superuser.com/a/1476941/1266379。我使用 chmod a+w 手动创建了 out.log 文件,然后加载了 plist - 导致错误 78。但是,通过删除手动创建的 out.log 文件,卸载然后加载 plist,out.log 文件会自动创建并成功写入。

这是在 macOS Big Sur v11.1 上完成的。

相关内容