Python 脚本/Unix 可执行文件在终端中运行,作为 Cron/Launchd 作业失败

Python 脚本/Unix 可执行文件在终端中运行,作为 Cron/Launchd 作业失败

我正在尝试配置 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 $PATHcron 作业并检查它是否包含 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

相关内容