我正在尝试配置 launchd 来触发 python 脚本/unix 可执行文件(即带有舍邦线)。当我加载 .plist 文件(如下)时,launchctl
显示状态 127,表示“指定的服务未随操作系统一起提供”。但是,当我将 .plist 文件中为“程序”输入的值复制并粘贴到 mac 终端中时,它运行正常。
我已将 stdout/stderr 重定向到终端(通过 .plist),它返回以下消息,
$ env: python3: 没有此文件或目录
Program
如果我将plist 中的值替换为一个简单的“hello world”批处理脚本,它就可以正常工作。
为什么 Python 程序 (urlwatch) 在终端中运行良好,但通过 launchd 调用时却返回错误?我该如何修复它?
Plist文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" \
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>local.careersWatch3</string>
<key>Program</key>
<string>/Users/justinmichael/Documents/urlwatch-master/urlwatch</string>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/dev/ttys000</string>
<key>StandardErrorPath</key>
<string>/dev/ttys000</string>
</dict>
</plist>
我最终想在一天中的设定时间运行该脚本,但现在我正在使用RunAtLoad
=true
进行测试目的,直到我可以让它正常工作。
加载到 launchd 并输出:
$ launchctl load ~/Library/LaunchAgents/local.careerswatch3.plist
$ env: python3: No such file or directory
调用来检查代理和输出的状态:
$ launchctl list | grep local.careersWatch3
- 127 local.careersWatch3
在终端中查找代码‘127’的含义:
$ launchctl error 127
127: The specified service did not ship with the operating system
答案1
问题出在环境变量上,具体来说,cron 运行的作业与我以登录用户身份在终端中调用的程序的 $PATH 不同。调用echo $PATH
cron 作业并检查它是否包含 python 解释器的目录可以帮助确认这是问题所在。
两种解决方案:
1)快速而粗略
找到 Python 解释器的安装位置,然后更改 unix 可执行文件/python 脚本顶部的 shebang 行以直接调用它。即
#!/usr/bin/env python3
变成
#!/usr/local/bin/python3
在这里,python 解释器是否在路径上并不重要,因为它的位置是明确给出的。缺点是它的位置现在是硬编码的,如果你将脚本移动到另一台计算机,如果 python 安装在不同的位置,脚本可能无法工作,无论是在 cron 中还是在终端中运行。
2)少快,少脏
编写一个 shell 脚本,如果 Python 解释器的位置尚未存在,则将其添加到路径中(根据这超级用户问题)然后调用 python 脚本。这样,脚本就不会被更改,也不会因为将其移动到安装了 python 的其他目录的计算机而意外损坏。
#!/bin/bash
# directory python is found in
dir="usr/local/bin"
#add to path if not there
if [ -d "$dir" ] && [[ ":$PATH:" != *":$dir:"* ]]; then
PATH="${PATH:+"$PATH:"}$dir"
fi
#Run program
/path/to/program/program_name
确保通过以下方式使脚本可执行chmod +x /path/to/script/script.sh