4

我想使用launchd每分钟运行一个python脚本。我的 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.turtle.script.plist</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/python</string>
        <string>/Users/turtle/Desktop/turtle.py</string>
        <string>/Users/turtle/Desktop/data/data.txt</string>
    </array>
    <key>StartInterval</key>
    <integer>60</integer>
</dict>
</plist>

这个 plist 文件看起来不错,因为我得到以下信息:

plutil -lint com.turtle.script.plist
com.turtle.script.plist: OK

当我从命令行运行该脚本时,该脚本有效:

/usr/bin/python /Users/turtle/Desktop/turtle.py /Users/turtle/Desktop/data/data.txt

我通过以下方式加载此 plist:

   launchctl load -w -F com.turtle.script.plist

我也试过:

sudo launchctl load -w -F com.turtle.script.plist

我加载了这个作业,python 脚本应该把一个文件写到磁盘上。然而,从来没有产生过文件。我检查了这份工作:

sudo launchctl list | grep com.turtle.script.plist

输出是:

- 1 com.turtle.script.plist

任何人都可以帮助解决问题吗?

4

3 回答 3

6

听起来脚本内部存在一些环境依赖性 - 本质上,它假设它运行的环境在您手动运行时是正确的,但在 launchd 运行时却不是。在对脚本一无所知的情况下,很难指出这可能是什么,但我可以建议一些事情来看看:

  • sudo launchctl不是更强大的版本launchctl,它做了一些明显不同的事情。你需要弄清楚你想要哪一个,然后使用它。

    当您launchctl作为普通用户(例如launchctl load)运行时,它会与您的 launchd 用户实例交互以管理启动代理——在您的用户会话中以您的用户身份运行的项目。

    当您launchctl以 root 身份运行时(例如sudo launchctl load),它与 launchd 的系统实例交互以管理启动守护进程——在系统上下文中以 root 身份运行的项目。

    您必须根据此脚本的功能来决定哪个是合适的。

  • 检查 system.log(您可以使用 Console 实用程序来查看它,或者tail -f /var/log/system.log)并查看它是否包含任何内容来指示脚本失败的原因。

  • 将条目添加到 launchd .plist 以记录脚本的输出,并查看其中是否包含任何错误消息或出现问题的其他指示:

    <key>StandardOutPath</key>
    <string>/tmp/turtle.out</string>
    <key>StandardErrorPath</key>
    <string>/tmp/turtle.err</string>
    

    编辑脚本以添加调试输出可能会有所帮助,因此您可以详细了解它的工作原理(/不工作)。

  • 脚本是否依赖于特定的工作目录和/或环境变量?如果是这样,请将适当的WorkingDirectory和/或EnvironmentVariables项目添加到 .plist。

于 2013-04-13T18:29:47.110 回答
1

尝试写入/tmp任何用户都可以写入的内容。即更改/Users/turtle/Desktop/data/data.txt/tmp/my_data.txt如果那是您的输出文件。

于 2013-04-13T17:21:40.000 回答
1

您的 .plist 文件位于~/Library/LaunchAgents

<?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>local.tf.check_up</string>
    <key>Program</key>
    <string>/Users/tf/.bin/check_up.py</string>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>/tmp/local.tf.check_up.stderr</string>
    <key>StandardOutPath</key>
    <string>/tmp/local.tf.check_up.stdout</string>
    <key>StartInterval</key>
    <integer>60</integer>
    <key>WorkingDirectory</key>
    <string>/tmp/</string>
</dict>
</plist>

你的脚本/Users/tf/.bin/check_up.py

#!/opt/local/bin/python

f = open('/Users/tf/Desktop/test.txt', 'a')
f.write('hello again 4\n')
f.close()

请注意,我使用python的是 MacPorts,它位于/opt/local/bin/. 如果您使用不同的 python 解释器,请将上面的行替换为任何$ which python返回值。

确保您的脚本是可执行的,并且只有您具有写入权限:

$ chmod 755 ~/.bin/check_up.py

测试脚本:运行它并查看它是否正常工作:

$ ~/.bin/check_up.py

加载 LaunchAgent:

$ launchctl load ~/Library/LaunchAgents/local.tf.check_up.plist
于 2015-09-22T10:23:30.927 回答