César César - 1 year ago 90
Python Question

Fabric not working with cron job

I'm trying to run a deploy script using pexpect and Fabric. This is what is happening:

$ crontab -l
# m h dom mon dow command
30 04 * * * /bin/bash /home/pedregal/Deploy/deploy.sh

$ ls -l
total 20
-rwxrwxr-- 1 pedregal pedregal 239 Nov 11 09:00 deploy.sh
-rw-rw-r-- 1 pedregal pedregal 271 Nov 9 21:33 expectfile.py
-rw-rw-r-- 1 pedregal pedregal 900 Nov 10 07:28 fabfile.py

deploy.sh (I'm a total shell scripting newbie, bear with me)



touch $LOG_FILE
python $EXPECT_FILE > $LOG_FILE 2>&1
mail -s "Auto-update log" cbustios@elpedregalsa.com < $LOG_FILE


# -*- coding: utf-8 -*-
import pexpect
import sys

child = pexpect.spawn('fab piura deploy', echo=False)
child.logfile = sys.stdout


# -*- coding: utf-8 -*-
from __future__ import with_statement
import os
from os.path import join, dirname

from dotenv import load_dotenv
from fabric.api import cd, env, prefix, run, sudo, warn_only

DOTENV_PATH = join(dirname(__file__), '.env')
GESTAGRO_PATH = '/home/pedregal/Projects/gestagro/gestagro/'
VENV_PATH = '/home/pedregal/Environments/gestagro/venv/bin/activate'
ACTIVATE_VENV = 'source %s' % (VENV_PATH)

def piura():
env.hosts = [
env.passwords = {
'pedregal@': os.environ.get('PASSWORD_PIURA'),

def deploy():
with cd(GESTAGRO_PATH), prefix(ACTIVATE_VENV), warn_only():
run('hg pull -u')
run('python manage.py migrate --no-color')
run('python manage.py collectstatic --noinput --no-color')
sudo('nginx -s reload')
sudo('supervisorctl restart gestagro')

If I run
manually it runs perfectly fine, however, I'm receiving an email with the following traceback from the cron job:

Traceback (most recent call last):
File "/home/pedregal/Deploy/expectfile.py", line 5, in <module>
child = pexpect.spawn('fab piura deploy', echo=False)
File "/usr/local/lib/python2.7/dist-packages/pexpect/pty_spawn.py", line 194, in __init__
self._spawn(command, args, preexec_fn, dimensions)
File "/usr/local/lib/python2.7/dist-packages/pexpect/pty_spawn.py", line 267, in _spawn
'executable: %s.' % self.command)
pexpect.exceptions.ExceptionPexpect: The command was not found or was not executable: fab.

I thought the installation of Fabric was system-wide, what am I missing?

Answer Source

A cronjob doesn't run load .bash_profile nor your .bashrc, these are source'd by your shell. But cron does not run through your shell so you have to setup the required environment variables (e.g. PATH) manually from the running script.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download