Frage

Ich betreibe eine Python-Shell von crontab jede Minute:

* * * * * /home/udi/foo/bar.py

/home/udi/foo hat einige notwendige Unterverzeichnisse, wie /home/udi/foo/log und /home/udi/foo/config, die /home/udi/foo/bar.py bezeichnet.

Das Problem ist, dass crontab führt das Skript aus einem anderen Arbeitsverzeichnis, so zu öffnen ./log/bar.log Versuch fehlschlägt.

Gibt es eine schöne Möglichkeit, um das Skript zu sagen, das Arbeitsverzeichnis in das Skript der eigenen Verzeichnis zu ändern? Ich würde Lust auf eine Lösung, die für jeden Skript Standort funktionieren würde, anstatt explizit das Skript zu sagen, wo es ist.

EDIT:

os.chdir(os.path.dirname(sys.argv[0]))

War die kompakteste elegante Lösung. Vielen Dank für Ihre Antworten und Erklärungen!

War es hilfreich?

Lösung

Dies wird Ihr aktuelles Arbeitsverzeichnis ändern, so dass relative Pfade Öffnen funktioniert:

import os
os.chdir("/home/udi/foo")

Allerdings bittet Sie, wie in ändern, was auch immer Verzeichnis Ihres Python-Skript befindet, auch wenn Sie nicht wissen, was Verzeichnis, das sein wird, wenn Sie Ihren Skript gerade schreiben. Um dies zu tun, können Sie die os.path Funktionen zur Verfügung:

import os

abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)

Dieses den Dateinamen des Skripts nimmt, wandelt es in einen absoluten Pfad, extrahiert dann das Verzeichnis dieses Weges ändert sich dann in dieses Verzeichnis.

Andere Tipps

Sie können eine kürzere Version erhalten, indem sys.path[0] verwendet wird.

os.chdir(sys.path[0])

http://docs.python.org/library/sys.html # sys.path

  

Wie initialisiert beim Programmstart, das erste Element dieser Liste,   path[0], ist das Verzeichnis, das das Skript enthält, das verwendet wurde, um   rufen Sie das Python-Interpreter

Tu das nicht.

Ihre Skripte und Ihre Daten sollten nicht in einem großen Verzeichnis püriert werden. Setzen Sie den Code in einigen bekannten Ort (site-packages oder /var/opt/udi oder etwas) getrennt von Ihren Daten. Verwenden Sie gute Versionskontrolle auf Ihrem Code sicher sein, dass Sie voneinander getrennt aktuelle und frühere Versionen haben, damit Sie zurück zur vorherigen Versionen fallen können und zukünftige Versionen testen.

Fazit:. Sie mischen sich nicht von Code und Daten

Die Daten sind wertvoll. Code kommt und geht.

Geben Sie das Arbeitsverzeichnis als Befehlszeilenargument Wert. Sie können eine Standard als Umgebungsvariable bereitzustellen. Verwenden Sie es nicht ableiten (oder es erraten)

Machen Sie es ein erforderliches Argument Wert und dies tun.

import sys
import os
working= os.environ.get("WORKING_DIRECTORY","/some/default")
if len(sys.argv) > 1: working = sys.argv[1]
os.chdir( working )

Sie nicht „annehmen“ ein Verzeichnis auf den Speicherort Ihrer Software basiert. Es wird nicht gut auf lange Sicht funktionieren.

Ändern Sie Ihre crontab-Befehl

* * * * * (cd /home/udi/foo/ || exit 1; ./bar.py)

Die (...) startet eine Unterschale, die Ihr crond als einen einzigen Befehl ausführt. Die || exit 1 bewirkt, dass Ihr cronjob im Fall fehlschlagen, dass das Verzeichnis nicht verfügbar ist.

Auch wenn die anderen Lösungen auf lange Sicht für Ihre spezifische Scripts elegantere sein können, noch mein Beispiel in Fällen nützlich sein könnte, wo Sie das Programm nicht ändern können oder Befehl, den Sie ausführen möchten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top