launchd 在 El Capitan 中没有 'keep alive' 进程
launchd does not 'keep alive' processes in El Capitan
我试图确保进程始终处于 运行ning 状态,即使在它退出、崩溃或停止之后也是如此。它是一个读取串行线并写入数据库的小型二进制文件——没有什么太复杂的。如果读取失败,它会以退出代码 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 中一定有我错过的新内容?
进一步的实验揭示了答案。似乎只有 'Global Daemons' 等守护进程遵守重启和 RunAtLaunch 指令。我注意到 /Library/LaunchDaemons 中有几个 plist,例如 TeamViewer 和其他第三方程序。
有趣的是,可以将 SIGKILL 发送到属于 Apple 的进程,例如 ImageCaptureAgent,并且不遵守 KeepAlive 指令。这是一个 Apple 定义的代理 plist 文件,明确指出进程在被终止时应该重新启动,但事实并非如此。
我想知道 Apple 是否在较新版本中更改了此功能?
我试图确保进程始终处于 运行ning 状态,即使在它退出、崩溃或停止之后也是如此。它是一个读取串行线并写入数据库的小型二进制文件——没有什么太复杂的。如果读取失败,它会以退出代码 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 中一定有我错过的新内容?
进一步的实验揭示了答案。似乎只有 'Global Daemons' 等守护进程遵守重启和 RunAtLaunch 指令。我注意到 /Library/LaunchDaemons 中有几个 plist,例如 TeamViewer 和其他第三方程序。
有趣的是,可以将 SIGKILL 发送到属于 Apple 的进程,例如 ImageCaptureAgent,并且不遵守 KeepAlive 指令。这是一个 Apple 定义的代理 plist 文件,明确指出进程在被终止时应该重新启动,但事实并非如此。
我想知道 Apple 是否在较新版本中更改了此功能?