1

I'm on Ubuntu 20.04, and I am having issues setting up the crontab correctly using pyenv + pipenv together. Simply adding pipenv run python script.py to the cronjob does not work; I think it may be due to:

  1. the environment required by pyenv
  2. the non-interactive shell of cronjob

UPDATED BIG QUESTION

How do I use /home/jennings/.pyenv/shims/pipenv correctly in crontab??

I've checked $? for pipenv -v in run.sh scheduled in crontab, and it fails.

https://github.com/pyenv/pyenv#advanced-configuration

00. (for reference) Bash startup

pyenv requires these entries in these startup files for interactive/login shells I don't understand how to translate this to a non-interactive cronjob call. How do I set up my BASH_ENV to emmulate these environents below? https://stackoverflow.com/a/9954208/9335288

# ~/.profile
eval "$(pyenv init --path)"
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init --path)"
fi
# ~/.bashrc:
export PYENV_ROOT="$HOME/.pyenv"

I. Crontab

I am trying to effectively write a .profile for the cronjob... but if you a better solution, please let me know.

# CRONTAB

SHELL=/bin/bash
BASH_ENV="home/jennings/.custom_bash_env
# BASH_ENV="home/jennings/.profile"
# BASH_ENV="home/jennings/.bashrc"
* * * * * cd $PROJECT_DIR; ./run.sh

# BASH_ENV:

Should I point to .profile or .bashrc instead?*

# PYENV
#eval "$(pyenv init --path)"
#if command -v pyenv 1>/dev/null 2>&1; then
#  eval "$(pyenv init --path)"
#fi

# ENV VARIABLES
PYENV_ROOT="/home/jennings/.pyenv"
PYTHONPATH=$SOMEPLACE
PATH=all:of:them:paths

II. Project Folder

# run.sh:

#!/usr/bin/bash
# PYENV
eval "$(pyenv init --path)"
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init --path)"
fi
# actual pipenv command I'm trying to run
pipenv run python main.py

# main.py:

import this
# Does some python and logging

What I've tried and know

  • Pointing directly at the .profile and .bashrc doesn't work
  • run.sh will run okay; it's thepipenv step that fails
  • Scheduling other non-pipenv commands work fine

pyenv init block

  • Placed in the BASH_ENV file, the cronjob doesn't run at all
  • Placed in the run.sh, the cronjob now runs, but the pipenv run still fails

pipenv related

  • I've tried pipenv shell; which python to use that one in the crontab enjoy -- no cigar
Jennings
  • 438
  • 5
  • 17
  • `cron` does not run any of your interactive startup files. If you want to load settings from those, you need to explicitly `source` them. – tripleee Dec 09 '21 at 08:56
  • Using backslashes where you mean slash is rather distracting. Windows (bless its soul) accepts forward slash as a replacement for the OS native backslash directory separator, but backslash on Unix is always an escape character. – tripleee Dec 09 '21 at 08:57
  • @tripleee I have tried sourcing them, but it didn't work. How would you recommend doing that (in which file, in which order?). The `BASH_ENV=.custom_env`? And then .custom_env would contain something like `source .profile; source.bashrc`? – Jennings Dec 09 '21 at 09:02
  • @tripleee sorry about the slashes, my brain is fried from trying to figure this out. Fixed them tho – Jennings Dec 09 '21 at 09:03
  • I'm not familiar enough with `pyenv` internals to post an answer. What I usually do is combine `pyenv` with `venv` and then just activate the `venv` when I need it; but I know this is not common practice. – tripleee Dec 09 '21 at 09:05

1 Answers1

3

Cron has a limited environment. You have to declare the full path to the pipenv executable. Instead of using pipenv run python script.py you should use /usr/local/bin/pipenv run python script.py.

In your case the full path can be different which pipenv will give you the proper path.

This is explained in this post how to run pipenv in cronjob in ubuntu?

  • I have forgottent to mention that you also have to add a `cd /path/to/the/pipenv/project;` before your script, so that pipenv knows which environment he has to activate. – jean pierre huart Apr 29 '22 at 13:39
  • Thanks. I don't think I updated, but I also addressed the issue by removing `pyenv` from the equation. I just used the OS-level `python` and `pipenv` of the server instead (which means I'm locked on a particular python version, but as long as it works). Your comments are also true and definitely helpful – Jennings Apr 29 '22 at 18:21