启动的 plist 任务 python sys.path 错误

Launchd plist task python sys.path error

我正在尝试使用加载 python 脚本的 launchd 构建每日计划的 plist 任务,该脚本通过 sendgrid 向我发送包含 link 的电子邮件。

我的 python 发送电子邮件的脚本可以从命令行使用 python dailyemail.py(见下文)

import os, requests, bs4, sendgrid
from sendgrid.helpers.mail import *
url = 'https://apod.nasa.gov/apod/astropix.html'
sg = sendgrid.SendGridAPIClient(apikey=os.environ.get('SENDGRID_API_KEY'))
from_email = Email("xxx")
to_email = Email("xxx")
subject = "Astronomy Picture of the Day"
content = Content("text/plain", 'https://apod.nasa.gov/apod/astropix.html')
mail = Mail(from_email, subject, to_email, content)
response = sg.client.mail.send.post(request_body=mail.get())

当我在指定时间加载并启动我的 plist 任务时 运行s,但由于无法导入 requests, bs4 and sendgrid 模块而失败。 通过记录 sys.path 输出,我发现我的系统似乎正在从命令行加载两个略有不同的 Python 版本,而当我通过 launchd 运行 任务时(见输出结束和 plist 任务)。

我有两个问题:

  1. 如何解决这种差异?也有兴趣了解为什么 这些文件路径会有所不同吗?
  2. 是否有另一种方法可以将 python 模块加载/引用到 plist 任务中以使其正常工作?

谢谢!

系统:OSX El Capitan 10.11.3

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>
    <!-- The label should be the same as the filename without the extension -->
    <string>com.alexanderhandy.nasa</string>
    <!-- Specify how to run your program here -->
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/python</string>
        <string>/Users/alexanderhandy/Documents/Programming/Scripts/dailyemail.py</string>
    </array>
    <!-- Run every dat -->
    <key>StandardErrorPath</key>
    <string>/tmp/ahnasa.err</string>
    <key>StandardOutPath</key>
    <string>/tmp/ahnasa.out</string>
    <key>StartCalendarInterval</key>
      <dict>
          <key>Hour</key>
          <integer>12</integer>
          <key>Minute</key>
          <integer>34</integer>
      </dict>
</dict>
</plist>

错误日志

*Command line python sys.path*
 /Users/alexanderhandy/Documents/Programming/Scripts/usr/local/lib/python2.7/site-packages/setuptools-17.0-py2.7.egg/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python27.zip/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/usr/local/lib/python2.7/site-packages/Library/Python/2.7/site-packages

*plist task python sys.path*
/Users/alexanderhandy/Documents/Programming/Scripts/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC/Library/Python/2.7/site-packages

好的,这里不是 100% 确定,所以欢迎其他人改进这个答案。

-

在相关 PythonDocs 中阅读 system.path 的 Python2.7,然后解释它给出的输出,看来 Python 的命令行脚本版本是在 /usr/local/lib 下卸载,这意味着它是本地安装,而 LaunchDaemon 是 运行 基于系统的安装,位于 /System/Library/Frameworks/ 文件夹中。

我的预感是您可能通过 Homebrew 安装了 Python2.7,导致您最终得到 2 个不同版本的 Python。在整个 Whosebug 中,有许多相关的 questions/answers 关于这可能的优点和缺点。您可能已经针对 Homebrew 的版本安装了模块,但 LaunchDaemon 使用的是 macOS 预安装版本。

阅读 Python 上的 Homebrew Docs 我的下一个预感是,如果您更改:

<string>/usr/bin/python</string>

在您的 plist 任务中:

<string>/usr/bin/python2</string>

你应该没问题。

如果没有,请告诉我,因为可能有多种方法可以解决您的问题。