【问题标题】:launchd does not 'keep alive' processes in El Capitan在 El Capitan 中,launchd 不会“保持活动”进程
【发布时间】:2017-03-10 16:27:17
【问题描述】:

我试图确保一个进程始终在运行,即使在它退出、崩溃或停止之后也是如此。它是一个小型二进制文件,可以读取串行线路并写入数据库——没什么太复杂的。如果读取失败,它会以 exitcode 70 退出并捕获任何 SIGKILL 或 SIGTERM 事件并在实际退出之前优雅地关闭其数据库连接。

但是,进程不会在加载时启动(即使设置了此标志),如果它被杀死也不会重新启动。这是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>Disabled</key>
    <false/>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>blah.bloop.tag05</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/blah/Desktop/rfid</string>
        <string>-f/dev/tty.usbserial-FT32X30YBXB</string>
        <string>-n5</string>
        <string>-ctcp://127.0.01</string>
        <string>-v</string>
        <string>-x100000</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>/var/log/rfid.log</string>
    <key>StandardOutPath</key>
    <string>/var/log/rfid.log</string>
    <key>WorkingDirectory</key>
    <string>/Users/blah/Desktop</string>
</dict>
</plist>

此 plist 位于 ~/Library/LaunchAgents 中(相关用户可以轻松地停止和启动此过程)。

有什么想法吗?我知道还有其他进程正在重新启动,但我一生都无法弄清楚这个。我认为权限可能是它,但这些看起来都很好:/

我决定尝试另一个 plist,看看是不是我的守护程序有问题。原来,它已经启动了:

所以我决定使用程序 tail 进行快速测试。我想看看它是我的守护进程本身还是与launchd有关。看来launchd是问题所在。这是一个替代且简单的 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>KeepAlive</key>
        <true/>
        <key>Label</key>
        <string>test.test</string>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/bin/tail</string>
                <string>-f</string>
                <string>/var/log/system.log</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>StandardErrorPath</key>
        <string>/tmp/test.test.err</string>
        <key>StandardOutPath</key>
        <string>/tmp/test.test.out</string>
</dict>
</plist>

我使用以下命令启动此过程

launchctl load test.plist
launchctl start test.test

然后我通过使用 kill 命令向进程发送 SIGKILL 或 SIGTERM 来从另一个终端终止进程。 Launchd 无法重新启动进程。

我怀疑 El-Capitan 一定有一些我错过的新东西?

【问题讨论】:

  • 在描述中添加了更多内容。似乎由于某种原因,进程是:a)没有在负载下运行。 b) 在被杀死或终止时不会重新启动我怀疑在最近的 OSX 版本中需要加载作业或在 plist 中指定正确行为的方式发生了变化,但我能找到的所有文档都表明这将起作用。

标签: macos daemon osx-elcapitan launchd


【解决方案1】:

进一步的实验揭示了一个的答案。似乎只有守护程序,例如“全局守护程序”才尊重重新启动和 RunAtLaunch 指令。我注意到 /Library/LaunchDaemons 中有几个 plist,例如用于 TeamViewer 和其他第三方程序的这些。

有趣的是,可以将 SIGKILL 发送到属于 Apple 的进程,例如 ImageCaptureAgent,但 KeepAlive 指令不受尊重。这是一个 Apple 定义的代理 plist 文件,它明确指出如果进程被杀死,应该重新启动它,但它没有。

我想知道 Apple 是否在新版本中更改了此功能?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    • 2017-06-08
    相关资源
    最近更新 更多