16

为了演示我遇到的问题,我将使用这个简单的函数,它位于/Users/X/Code/python/example/start.py

def say_hello(name):
   print("Saying hello to {}".format(name))

say_hello("John")

pipenv用来设置我的包和环境。在这个文件夹中(旁边start.py),我还有四个其他文件- PipfilePipfile.lock和..envlog.txt

当我运行时pipenv run python start.py,一切正常,我得到一个输出。

现在我希望这个脚本每分钟运行一次,所以我设置了一个 cron 作业crontab -e,这是我最初在那里的:

* * * * * /usr/local/bin/pipenv run python /Users/X/Code/python/example/start.py >> /Users/X/Code/python/example/log.txt 2>&1

这给了我该文件中的错误转储log.txt

RuntimeError: Click will abort further execution because Python 3 was configured to use ASCII as encoding for the environment.  Consult http://click.pocoo.org/python3/for mitigation steps.

This system lists a couple of UTF-8 supporting locales that
you can pick from.  The following suitable locales where
discovered: af_ZA.UTF-8, am_ET.UTF-8, be_BY.UTF-8, bg_BG.UTF-8, ca_ES.UTF-8, cs_CZ.UTF-8, da_DK.UTF-8, de_AT.UTF-8, de_CH.UTF-8, de_DE.UTF-8, el_GR.UTF-8, en_AU.UTF-8....

经过大量的谷歌搜索,我得出的结论是环境设置不正确locales,所以我在该.env文件中添加了如下所示:

LC_ALL=en_GB.UTF-8
LANG=en_GB.UTF-8

然后我又花了几分钟查看log.txt一遍又一遍地出现相同的错误,然后我意识到当我调用时/usr/local/bin/pipenv,它实际上需要正确Pipfile的加载正确的环境。所以相反,我把我cron的改为:

* * * * * cd /Users/X/Code/python/example && /usr/local/bin/pipenv run python /Users/X/Code/python/example/start.py >> /Users/X/Code/python/example/log.txt 2>&1

所以从技术上讲,现在它应该cd进入文件夹然后运行这些pipenv东西,但我的文件中仍然出现同样的错误log

任何帮助将非常感激。

4

5 回答 5

12

尝试添加/usr/local/bin到您的PATH为好。似乎pipenv可能需要调用它所在路径中的其他应用程序。当 cron 运行作业时,它与登录 shell 时所获得的环境不同。

可能更容易创建一个从 cron 调用的包装脚本:

cd /Users/X/Code/python/example 
PATH=/usr/local/bin:$PATH
pipenv run python start.py >> /Users/X/Code/python/example/log.txt 2>&1
于 2018-03-25T06:27:13.423 回答
3

我最近遇到了一个使用pexpect并通过 cron 运行的 python 程序的问题。正如其他人提到的,cron 与输入 cron 脚本数据的用户没有相同的环境,即 $PATH。在我的情况下,我使用的 redhat 环境也有一个提供 python3.6 的软件集合(如本文redhat-py3 中所述)。

无论如何,我对 pipenv - cron 难题的解决方案是使用 penv 来创建具有所需依赖项的 virtualenv。然后使用 'pipenv shell' 获取一个 shell 命令,该命令可用于通过 cron 和 bash 激活 virtualenv。如果我已经使用 pipenv 安装了我的依赖项并创建了一个 Pipfile ,那么我可以使用来检查 virtualenv

pipenv check

如果我已经有一个 virtualenv,那么我将看到以下消息。

 Checking PEP 508 requirements…
 Passed!
 Checking installed package safety…
 All good!

然后我可以运行 pipenv shell

pipenv shell     

这应该导致以下结果

Launching subshell in virtual environment…
. /<path>/<to>/<virtualenv>/bin/activate

!!!注意句号“。” 在预期输出的第二行。然后可以将这一行放在我的 cron 脚本中(我推荐一个 shell 脚本)。然后由 cron 调用。

由 cron 运行并从@Chris Shaw 借来的最终脚本如下所示:

#!/bin/bash  
#or whatever shell you use
cd /Users/X/Code/python/example
. /<path>/<to>/<virtualenv>/bin/activate 
# you should specifiy the python version in the below command
#python2.7 start.py >> /Users/X/Code/python/example/log.txt 2>&1
python3 start.py >> /Users/X/Code/python/example/log.txt 2>&1

由于依赖于特定的 virtualenv,而不是 pipenv 命令,此解决方案很脆弱。因此,如果您重新创建 virtualenv ,它可能会导致一条新路径。这将需要在您的 shell 脚本中更新。但它消除了对 pipenv 为 cron 提供 shell 环境的依赖。

作为补充说明,如果 cron 作业开始失败,我建议通过电子邮件或类似方式添加警报。Cron 通常会默默地失败,并且会很高兴地继续进行而不做你想做的事情,直到你发现失败为止。

于 2019-08-06T16:00:57.137 回答
3

对我来说,直接运行 virtualenv 的 Python 可执行文件就足够了,例如:

0 5 * * * /home/user/.local/share/virtualenvs/project-30iXwYpI/bin/python /home/user/project/script.py

正如 wordtronix 指出的那样,您可以通过运行 pipenv 并查看它在控制台上打印的内容来获取 virtualenv 的位置。

于 2021-03-04T16:19:55.777 回答
1

我刚刚将此文件添加到我的工作区,如果您有一个脚本目录并利用更多优势或使用 pipenv 中的 [scripts] 的 PIPENV_PIPFILE,您可以修改它。

#!/usr/bin/env bash
script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
PIPFILE=$script_dir/Pipfile
export PIPENV_PIPFILE=$(cd $(dirname $PIPFILE) && pwd)/$(basename $PIPFILE)
pipenv run python $script_dir/generate_avatar.py

那么cronjob就是:

* * * * *  $FOODIR/run.sh
于 2020-04-02T18:16:41.893 回答
0

潜在问题:默认情况下,您的 cronjobs 无法访问您的环境变量

我的设置略有不同,但也尝试做一些 pipenv 和 crontab 的东西。我通过使用文件路径解决了我的问题/usr/local/bin/pipenv,并且还在 cron 脚本的开头设置了导出的环境变量(使用 找到printenv)。

于 2019-12-18T15:26:37.750 回答