如何在Mac上每10秒以root用户身份运行一个ruby脚本?

时间:2015-05-10 18:44:52

标签: macos launchd

我在/ Library / LaunchDemons中有以下内容,如com.me.filechecker.plist

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!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>File Checker</string>
        <key>StartInterval</key>
        <integer>10</integer>
        <key>Program</key>
        <string>/usr/bin/ruby "/Users/me/projects/filechecker/filechecker.rb"</string>
    </dict>
</plist>

我也跑了

sudo chown root /Library/LaunchDaemons/com.me.filechecker.plist

sudo chmod a+x /Library/LaunchDaemons/com.me.filechecker.plist

sudo launchctl load -w /Library/LaunchDaemons/com.me.filechecker.plist

它似乎没有运行(或者如果它正在运行,它没有做任何事情)。我该如何调试它并使其工作?

2 个答案:

答案 0 :(得分:2)

可执行文件名及其参数的传递方式应与execvp函数相同。您必须分别传递可执行文件名和所有参数。参数应该在ProgramArguments键中传递:

    <key>Program</key>
    <string>/usr/bin/ruby</string>
    <key>ProgramArguments</key>
    <array>
       <string>/usr/bin/ruby</string>
       <string>/Users/me/projects/filechecker/filechecker.rb</string>
    </array>

在这种情况下,您也可以跳过Program键。更多man launchd.plist

 Program <string>
 This key maps to the first argument of execvp(3).  If this key is missing, then the first element of
 the array of strings provided to the ProgramArguments will be used instead.  This key is required in
 the absence of the ProgramArguments key.

 ProgramArguments <array of strings>
 This key maps to the second argument of execvp(3).  This key is required in the absence of the Program
 key. Please note: many people are confused by this key. Please read execvp(3) very carefully!

答案 1 :(得分:2)

补充baf's helpful answer(显示如何使用ProgramArguments键正确调用带有参数的可执行文件):

虽然使*.plist文件可执行文件不会造成伤害,但是没有必要这样做 重要的是文件:

  1. 必须由作业运行的用户所拥有(您已使用sudo chown root完成此操作,但sudo chown root:wheel更适合一致性。)< / LI> 出于安全原因,
  2. 不得分组或世界可写;因此,/Library/LaunchDaemons中的*.plist文件作为root用户(默认情况下)运行的典型文件在ls -l的输出行的开头报告以下内容: -rw-r--r-- 1 root wheel ...
  3. 遗憾的是,

    launchctl load只会在*.plist文件语法无效时生成错误消息,并且通常始终设置退出代码{{ 1}},即使出现错误。

    排查打开0 并查找Console.app条目:

    如果我在加载com.apple.xpc.launchd文件后执行此操作,我会看到几个相关条目,特别是这一条:

    *.plist

    这告诉我们5/10/15 11:33:38.653 PM com.apple.xpc.launchd[1]: (File Checker[61800]) Could not find and/or execute program specified by service: 2: No such file or directory: /usr/bin/ruby "/Users/me/projects/filechecker/filechecker.rb" 认为可执行文件路径是整个字符串 launchd,因为/usr/bin/ruby "/Users/me/projects/filechecker/filechecker.rb"密钥必须包含可执行路径。

    根据baf's answer建议的更正,Program应该正确调用命令。