python: cambia la directory di lavoro degli script nella propria directory dello script

StackOverflow https://stackoverflow.com/questions/1432924

  •  07-07-2019
  •  | 
  •  

Domanda

Eseguo una shell Python da crontab ogni minuto:

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

/ home / udi / foo ha alcune sottodirectory necessarie, come / home / udi / foo / log e / home / udi / foo / config , a cui /home/udi/foo/bar.py fa riferimento.

Il problema è che crontab esegue lo script da una diversa directory di lavoro, quindi il tentativo di aprire ./log/bar.log non riesce.

C'è un buon modo per dire allo script di cambiare la directory di lavoro nella propria directory dello script? Vorrei una soluzione che funzionasse per qualsiasi posizione dello script, piuttosto che dire esplicitamente allo script dove si trova.

Modifica

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

Era la soluzione elegante più compatta. Grazie per le risposte e le spiegazioni!

È stato utile?

Soluzione

Questo cambierà la tua directory di lavoro corrente in modo che l'apertura dei relativi percorsi funzionerà:

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

Tuttavia, hai chiesto come cambiare in qualunque directory si trova il tuo script Python, anche se non sai quale directory sarà quando stai scrivendo il tuo script. Per fare ciò, puoi usare le funzioni os.path :

import os

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

Questo prende il nome del tuo script, lo converte in un percorso assoluto, quindi estrae la directory di quel percorso, quindi cambia in quella directory.

Altri suggerimenti

Puoi ottenere una versione più breve usando sys.path [0] .

os.chdir(sys.path[0])

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

  

Come inizializzato all'avvio del programma, il primo elemento di questo elenco,    path [0] , è la directory che contiene lo script utilizzato   invoca l'interprete Python

Non farlo.

I tuoi script e i tuoi dati non devono essere uniti in un'unica grande directory. Metti il ??tuo codice in una posizione nota ( pacchetti del sito o / var / opt / udi o qualcosa del genere) separato dai tuoi dati. Usa un buon controllo della versione sul tuo codice per assicurarti di avere le versioni attuali e precedenti separate l'una dall'altra in modo da poter ricorrere alle versioni precedenti e testare le versioni future.

Conclusione: non mescolare codice e dati.

I dati sono preziosi. Il codice va e viene.

Fornire la directory di lavoro come valore dell'argomento della riga di comando. È possibile fornire un valore predefinito come variabile di ambiente. Non dedurlo (o indovinarlo)

Renderlo un valore argomento richiesto e farlo.

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

Non " presumere " una directory basata sulla posizione del software. Non funzionerà bene a lungo termine.

Cambia il tuo comando crontab in

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

Il (...) avvia una sotto-shell che la tua crond esegue come singolo comando. Il || exit 1 fa fallire il tuo cronjob nel caso in cui la directory non sia disponibile.

Sebbene le altre soluzioni possano essere più eleganti a lungo termine per i tuoi script specifici, il mio esempio potrebbe essere comunque utile nei casi in cui non è possibile modificare il programma o il comando che si desidera eseguire.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top