【问题标题】:Creating a simple Hello World tool that runs as a daemon创建一个作为守护进程运行的简单 Hello World 工具
【发布时间】:2012-03-10 20:22:27
【问题描述】:

我在 Xcode 中构建了命令行工具 (Foundation) 模板。它只是将“Hello World”记录到控制台。main.m 中只有一个类。代码如下:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])

{

   @autoreleasepool {

       // insert code here...
       NSLog(@"Hello, World!");

   }
   return 0;

}

现在我想将它作为守护进程运行,并每 10 秒将“Hello World”记录到控制台。所以我将产品/二进制文件移到了我的 Mac 上的 /tmp 中。我为 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>Label</key>
    <string>helloDaemon</string>
    <key>ProgramArguments</key>
    <array>
        <string>/tmp/helloDaemon</string>
    </array>
    <key>StartInterval</key>
    <integer>10</integer>
</dict>
</plist>

我使用 launchctl 加载了 plist,但在控制台中看不到任何“Hello World”。相反,我得到了这个:

11/03/2012 00:55:35.141 com.apple.launchd: (helloDaemon) Throttling respawn: Will start in 1 seconds
11/03/2012 00:55:45.141 com.apple.launchd: (helloDaemon) Throttling respawn: Will start in 2 seconds
11/03/2012 00:55:55.140 com.apple.launchd: (helloDaemon) Throttling respawn: Will start in 3 seconds

那么到底出了什么问题?

【问题讨论】:

  • 你在哪里安装了launchd plist?
  • @RobKeniger 我使用launchctl 来安装plist。此外,当我以 root 用户身份(使用 sudo)加载它时,它应该已经安装在 /Library/LaunchDaemons 中。但是好吧,我的 plist 没有复制到那个目录中(我认为只有在重新启动时启动的守护进程才会放在那里)。所以我手动将它复制到/Library/LaunchDaemons,但仍然没有运气。
  • @RobKeniger 但我认为它是由launchctl正确加载的。当我输入 sudo launchctl list 时,它会列出我的守护进程,状态为 0。
  • 好的,显然我的守护进程正在工作。我没有将日志记录到控制台,而是将输出定向到一个文件,并且它起作用了。所以出于某种原因,NSLogs 不起作用。

标签: macos cocoa launchd


【解决方案1】:

只需添加到您的启动列表中

<key>StandardOutPath</key>
<string>/yourpath/sample.log</string>

之后你可以tail -f它。

更多信息在这里: http://developer.apple.com/library/mac/technotes/tn2083/_index.html#//apple_ref/doc/uid/DTS10003794-CH1-SUBSECTION39

【讨论】:

    【解决方案2】:

    NSLog 不起作用,因为当您启动一个恶魔进程时,它没有附加任何标准 io 套接字或文件句柄。它们必须被专门分配。 Dalrymple 和 Hillegass 的“Advanced Mac OS X Programming (chapter 20)”一书中提供了有关如何创建适当的守护进程以及如何编写控制台和 syslog 的良好资源。

    他们已经定义了一个框架程序来解决您强调的 io 问题。我记得不久前读过它,我想也许有一天我会需要它。作者展示了一个使用 syslog.h 库的示例,该库使用 openlog() 和 syslog() 进行简单通信。他们还展示了一些其他较低级别的与文件甚至套接字(用于服务器等)通信的方法。

    当有人可以告诉我如何做某事而不是参考某事时,我总是很感激,但在这种情况下,这是我能做的最好的事情。祝你好运。

    【讨论】:

    • 我的 NSLog 一直在我的 OS X 守护进程中。您可以在系统日志中找到输出。
    【解决方案3】:

    使用plist 文件中的以下键,我可以获得大部分日志。但有时如果我在日志文件中获得所有NSLog 输出,我会感到困惑。对我来说,有时似乎缺少一些日志行。

    我不确定是否记录了 LaunchDaemon 的所有 NSLog 输出,或者由于系统优先级而跳过了一些输出。

    <key>StandardOutPath</key>
                    <string>/var/log/mydaemon.log</string>
            <key>StandardErrorPath</key>
                    <string>/var/log/mydaemon.log</string>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-18
      • 1970-01-01
      • 2014-07-03
      相关资源
      最近更新 更多