Question

Je lance un shell Python à partir de crontab toutes les minutes:

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

/ home / udi / foo contient certains sous-répertoires nécessaires, tels que / home / udi / foo / log et / home / udi / foo / config , auquel /home/udi/foo/bar.py fait référence.

Le problème est que crontab exécute le script à partir d'un autre répertoire de travail. Par conséquent, essayer d'ouvrir ./ log / bar.log échoue.

Y a-t-il un bon moyen de dire au script de changer le répertoire de travail en son propre répertoire? Je souhaiterais une solution qui fonctionnerait pour n’importe quel emplacement de script, plutôt que de dire explicitement où il se trouve.

EDIT:

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

était la solution élégante la plus compacte. Merci pour vos réponses et vos explications!

Était-ce utile?

La solution

Ceci changera votre répertoire de travail actuel pour que l'ouverture des chemins relatifs fonctionne:

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

Cependant, vous avez demandé comment changer de répertoire dans lequel se trouve votre script Python, même si vous ne savez pas de quel répertoire il s'agira lors de l'écriture de votre script. Pour ce faire, vous pouvez utiliser les fonctions os.path :

import os

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

Ceci prend le nom de fichier de votre script, le convertit en chemin absolu, puis extrait le répertoire de ce chemin, puis le modifie dans ce répertoire.

Autres conseils

Vous pouvez obtenir une version plus courte en utilisant sys.path [0] .

os.chdir(sys.path[0])

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

  

Initialisé au démarrage du programme, le premier élément de cette liste,    chemin [0] est le répertoire contenant le script utilisé pour   invoquer l'interpréteur Python

Ne faites pas ça.

Vos scripts et vos données ne doivent pas être écrasés dans un seul grand répertoire. Placez votre code dans un emplacement connu ( packages de site ou / var / opt / udi ou quelque chose d'autre) distinct de vos données. Utilisez un bon contrôle de version sur votre code pour vous assurer que les versions actuelles et précédentes sont séparées les unes des autres afin de pouvoir revenir aux versions précédentes et tester les versions futures.

Conclusion: ne mélangez pas le code et les données.

Les données sont précieuses. Le code va et vient.

Indiquez le répertoire de travail sous forme d'argument de ligne de commande. Vous pouvez fournir une valeur par défaut en tant que variable d'environnement. Ne le déduisez pas (ou ne le devinez pas)

Faites-en une valeur d'argument obligatoire et faites ceci.

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

Ne pas "assumer" un répertoire basé sur l'emplacement de votre logiciel. Cela ne fonctionnera pas bien à long terme.

Modifiez votre commande crontab en

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

Le (...) démarre un sous-shell que votre crond exécute en une seule commande. Le || exit 1 entraîne l’échec de votre tâche cron au cas où le répertoire ne serait pas disponible.

Bien que les autres solutions soient peut-être plus élégantes à long terme pour vos scripts spécifiques, mon exemple pourrait néanmoins être utile dans les cas où vous ne pouvez pas modifier le programme ou la commande à exécuter.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top