it-swarm.com.de

Cron und virtualenv

Ich versuche, einen Django Verwaltungsbefehl von cron aus auszuführen. Ich verwende virtualenv, um mein Projekt in einer Sandbox zu halten.

Ich habe hier und anderswo Beispiele gesehen, die zeigen, wie Verwaltungsbefehle in virtualenv ausgeführt werden:

0 3 * * * source /home/user/project/env/bin/activate && /home/user/project/manage.py command arg

Obwohl syslog einen Eintrag anzeigt, zu dem der Task hätte gestartet werden sollen, wird dieser Task nie ausgeführt (die Protokolldatei für das Skript ist leer). Wenn ich die Zeile manuell über die Shell ausführe, funktioniert sie wie erwartet.

Die einzige Möglichkeit, den Befehl derzeit über cron auszuführen, besteht darin, die Befehle aufzubrechen und sie in ein dummes Bash-Wrapper-Skript zu schreiben:

#!/bin/sh
source /home/user/project/env/bin/activate
cd /home/user/project/
./manage.py command arg

BEARBEITEN:

ars hat eine funktionierende Kombination von Befehlen entwickelt:

0 3 * * * cd /home/user/project && /home/user/project/env/bin/python /home/user/project/manage.py command arg

Zumindest in meinem Fall hat das Aufrufen des Aktivierungsskripts für virtualenv nichts bewirkt. Das funktioniert, so weiter mit der Show.

203
John-Scott

Sie sollten dazu in der Lage sein, in Ihrer virtuellen Umgebung das python zu verwenden:

/home/my/virtual/bin/python /home/my/project/manage.py command arg

BEARBEITEN: Wenn sich Ihr Django Projekt nicht im PYTHONPATH befindet, müssen Sie in das richtige Verzeichnis wechseln:

cd /home/my/project && /home/my/virtual/bin/python ...

Sie können auch versuchen, den Fehler von cron aus zu protokollieren:

cd /home/my/project && /home/my/virtual/bin/python /home/my/project/manage.py > /tmp/cronlog.txt 2>&1

Eine andere Sache, die Sie versuchen sollten, ist die gleiche Änderung in Ihrem manage.py Skript ganz oben:

#!/home/my/virtual/bin/python
225
ars

Das Ausführen von source aus einer Cron-Datei funktioniert nicht, da Cron /bin/sh Als Standard-Shell verwendet, die source nicht unterstützt. Sie müssen die Shell-Umgebungsvariable auf /bin/bash Setzen:

Shell=/bin/bash
*/10 * * * * root source /path/to/virtualenv/bin/activate && /path/to/build/manage.py some_command > /dev/null

Es ist schwierig zu erkennen, warum dies fehlschlägt, da /var/log/syslog Die Fehlerdetails nicht protokolliert. Am besten, Sie geben sich selbst einen Alias ​​als root, damit Sie per E-Mail über Cron-Fehler informiert werden. Fügen Sie sich einfach zu /etc/aliases Hinzu und führen Sie sendmail -bi Aus.

Weitere Informationen hier: http://codeinthehole.com/archives/43-Running-Django-cronjobs-within-a-virtualenv.html

der obige Link wurde geändert zu: https://codeinthehole.com/tips/running-Django-cronjobs-within-a-virtualenv/

88

Suchen Sie nicht weiter:

0 3 * * * /usr/bin/env bash -c 'cd /home/user/project && source /home/user/project/env/bin/activate && ./manage.py command arg' > /dev/null 2>&1

Allgemeiner Ansatz:

* * * * * /usr/bin/env bash -c 'YOUR_COMMAND_HERE' > /dev/null 2>&1

Das Schöne daran ist, dass Sie die Variable Shell für crontab NICHT von sh in bash ändern müssen.

10
Basil Musa

Anstatt sich mit virtuellen Shebangs zu beschäftigen, müssen Sie nur PATH auf der Crontab voranstellen.

Führen Sie in einer aktivierten virtuellen Umgebung diese drei Befehle aus und python Skripte sollten einfach funktionieren:

$ echo "PATH=$PATH" > myserver.cron
$ crontab -l >> myserver.cron
$ crontab myserver.cron

Die erste Zeile der Crontab sollte nun so aussehen:

PATH=/home/me/virtualenv/bin:/usr/bin:/bin:  # [etc...]
10
joemaller

Die einzige richtige Möglichkeit, python cron-Jobs unter Verwendung eines virtuellen Env auszuführen, besteht darin, die Umgebung zu aktivieren und dann die python auszuführen, um Ihren Code auszuführen.

Eine Möglichkeit, dies zu tun, ist die Verwendung von virtualenvs activate_this in Ihrem python Skript, siehe: http://virtualenv.readthedocs.org/en/latest/userguide.html#using-virtualenv-without-bin-python

Eine andere Lösung besteht darin, den gesamten Befehl zu wiederholen, einschließlich der Aktivierung der Umgebung und der Weiterleitung in /bin/bash. Betrachten Sie dies für Ihre /etc/crontab:

***** root echo 'source /env/bin/activate; python /your/script' | /bin/bash
9
Ivanhoe

Die beste Lösung für mich war für beide

  • verwenden Sie die Binärdatei python im Verzeichnis venv bin /
  • legen Sie den Pfad python fest, um das Verzeichnis venv modules einzuschließen.

man python erwähnt das Ändern des Pfads in Shell unter $PYTHONPATH oder in python mit sys.path

In anderen Antworten werden Ideen für die Verwendung der Shell genannt. Wenn ich in Python die folgenden Zeilen zu meinem Skript hinzufüge, kann ich es direkt in cron erfolgreich ausführen.

import sys
sys.path.insert(0,'/path/to/venv/lib/python3.3/site-packages');

So sieht es in einer interaktiven Sitzung aus:

Python 3.3.2+ (default, Feb 28 2014, 00:52:16) 
[GCC 4.8.1] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> import sys

>>> sys.path
['', '/usr/lib/python3.3', '/usr/lib/python3.3/plat-x86_64-linux-gnu', '/usr/lib/python3.3/lib-dynload']

>>> import requests
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'requests'   

>>> sys.path.insert(0,'/path/to/venv/modules/');

>>> import requests
>>>
3
here

Ich möchte dies hinzufügen, da ich einige Zeit damit verbracht habe, das Problem zu lösen, und hier keine Antwort für die Kombination der Variablenverwendung in cron und virtualenv gefunden habe. Vielleicht hilft es jemandem.

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DIR_SMTH="cd /smth"
VENV=". venv/bin/activate"
CMD="some_python_bin do_something"
# m h  dom mon dow   command
0 * * * * $DIR_SMTH && $VENV && $CMD -k2 some_target >> /tmp/crontest.log 2>&1

Es hat nicht gut funktioniert, als es wie konfiguriert war

DIR_SMTH = "cd/smth &&. Venv/bin/activate"

Danke @ davidwinterbottom , @ reed-sandberg und @ mkb für die richtige Richtung. Die akzeptierte Antwort funktioniert tatsächlich einwandfrei, bis Ihr python ein Skript ausführen muss, das ein anderes python binary aus dem Verzeichnis venv/bin ausführen muss.

2
Dmitriy