Ich habe ein Problem mit einem Shell-Skript getroffen, das alle 30 Minuten in cron auf einem Redhat 6-Server ausgeführt werden soll. Das Shell-Skript ist im Grunde nur ein Befehl zum Ausführen eines Python-Skripts.
Die native Python-Version auf dem Server ist 2.6.6, die für dieses Skript erforderliche Python-Version ist jedoch Python 2.7 und höher. Ich kann dies problemlos in der Befehlszeile ausführen, indem Sie den Befehl "scl" verwenden (dieses Beispiel enthält den Befehl python -V, um die Versionsänderung anzuzeigen):
$ python -V
Python 2.6.6
$ scl enable python27 bash
$ python -V
Python 2.7.3
An dieser Stelle kann ich die Python 2.7.3-Skripte über die Kommandozeile kein Problem ausführen.
Hier ist der Haken.
Wenn Sie den Befehl scl enable python27 bash
absetzen, wird eine neue bash-Shell-Sitzung gestartet, die (wieder) für interaktive Befehlszeilen geeignet ist. Wenn Sie dies jedoch innerhalb eines Shell-Skripts tun, wird das Skript, sobald es den Bash-Befehl ausführt, wegen der neuen Sitzung beendet.
Hier ist das Shell-Skript, das fehlschlägt:
#!/bin/bash
cd /var/www/python/scripts/
scl enable python27 bash
python runAllUpserts.py >/dev/null 2>&1
Es stoppt einfach, sobald es Zeile 4 erreicht, weil "bash" es aus dem Skript heraus in eine neue Bash-Shell zieht. So sieht es nie den eigentlichen Python-Befehl, den ich zum Ausführen brauche.
Wenn alle 30 Minuten ausgeführt wird, wird jedes Mal eine neue Bash hinzugefügt, was ein weiteres Problem darstellt.
Ich bin nicht bereit, die native Python-Version auf dem Server jetzt aus mehreren Gründen auf 2.7.3 zu aktualisieren. Die Redhat-Yum-Repos verfügen noch nicht über Python 2.7.3, und eine manuelle Installation wäre außerhalb des Yum-Aktualisierungssystems. Nach meinem Verständnis läuft yum selbst auf Python 2.6.x.
Hier habe ich die Methode zur Verwendung von scl gefunden
Alles in einem Heredoc in der SCL-Umgebung zu tun, ist die beste Option, IMO:
scl enable python27 - << \EOF
cd /var/www/python/scripts/
python runAllUpserts.py >/dev/null 2>&1
EOF
Eine andere Möglichkeit besteht darin, nur den zweiten Befehl (der einzige, der Python verwendet) in der scl-Umgebung direkt auszuführen:
cd /var/www/python/scripts/
scl enable python27 "python runAllUpserts.py >/dev/null 2>&1"
scl enable python27 bash
aktiviert eine virtuelle Python-Umgebung.
Sie können dies aus einem Bash-Skript heraus tun, indem Sie einfach das Aktivierungs-Skript der virtuellen Umgebung des SCL-Pakets verwenden, das sich unter /opt/rh/python27/enable
befindet.
Beispiel:
#!/bin/bash
cd /var/www/python/scripts/
source /opt/rh/python27/enable
python runAllUpserts.py >/dev/null 2>&1
Ist es nicht am einfachsten, nur Ihr Python-Skript direkt zu verwenden? test_python.py
:
#!/usr/bin/env python
import sys
f = open('/tmp/pytest.log','w+')
f.write(sys.version)
f.write('\n')
f.close()
dann in deinem crontab:
2 * * * * scl python27 enable $HOME/test_python.py
Stellen Sie sicher, dass Sie test_python.py
ausführbar machen.
Eine andere Alternative ist, ein Shell-Skript aufzurufen, das den Python aufruft. test_python.sh
:
#/bin/bash
python test_python.py
in deiner crontab:
2 * * * * scl python27 enable $HOME/test_python.sh
Einzeiler
scl enable python27 'python runAllUpserts.py >/dev/null 2>&1'
Ich verwende es auch mit den Devtoolsets auf dem CentOS 6.x
[email protected]_Host:~/tmp# scl enable devtoolset-1.1 'gcc --version'
gcc (GCC) 4.7.2 20121015 (Red Hat 4.7.2-5)
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Ich habe dieses scl
-Zeug nur einmal gesehen und habe keinen Zugriff auf ein System, auf dem es installiert ist. Aber ich denke, es ist nur so, dass PATH und einige andere Umgebungsvariablen so eingestellt werden, dass sie vage ähnlich sind wie unter virtualenv
.
Vielleicht würde das Ändern des Skripts für den Aufruf des bash
-Unterprozesses python
funktionieren:
#!/bin/bash
cd /var/www/python/scripts/
(scl enable python27 bash -c "python runAllUpserts.py") >/dev/null 2>&1
Die Instanz von python
in der Shell des Subprozesses bash
sollte Ihre 2.7.x-Kopie sein ... und alle anderen von scl
vorgenommenen Umgebungseinstellungen sollten damit vererbt werden.