name - python directory path
python: cambie el directorio de trabajo de scripts al propio directorio del script (4)
Cambie su comando crontab a
* * * * * (cd /home/udi/foo/ || exit 1; ./bar.py)
El (...)
inicia un subcorazón que tu crond ejecuta como un solo comando. El || exit 1
|| exit 1
hace que su cronjob falle en caso de que el directorio no esté disponible.
Aunque las otras soluciones pueden ser más elegantes a largo plazo para sus scripts específicos, mi ejemplo podría ser útil en los casos en que no pueda modificar el programa o comando que desea ejecutar.
Ejecuto un shell python desde crontab cada minuto:
* * * * * /home/udi/foo/bar.py
/home/udi/foo
tiene algunos subdirectorios necesarios, como /home/udi/foo/log
y /home/udi/foo/config
, a los que se /home/udi/foo/bar.py
referencia /home/udi/foo/bar.py
.
El problema es que crontab
ejecuta el script desde un directorio de trabajo diferente, por lo que intenta abrir ./log/bar.log
falla.
¿Hay alguna manera de decirle al script que cambie el directorio de trabajo al propio directorio del script? Me gustaría una solución que funcione para cualquier ubicación de script, en lugar de decirle explícitamente dónde está el script.
EDITAR:
os.chdir(os.path.dirname(sys.argv[0]))
Fue la solución elegante más compacta. ¡Gracias por tus respuestas y explicaciones!
Esto cambiará su directorio de trabajo actual para que funcionen las rutas relativas de apertura:
import os
os.chdir("/home/udi/foo")
Sin embargo, preguntaste cómo cambiar al directorio en el que esté ubicado tu script de Python, incluso si no sabes qué directorio será cuando estés escribiendo tu script. Para hacer esto, puede usar las funciones os.path
:
import os
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)
Esto toma el nombre de archivo de su script, lo convierte en una ruta absoluta, luego extrae el directorio de esa ruta, luego cambia a ese directorio.
No hagas esto
Sus scripts y sus datos no se deben mezclar en un gran directorio. Coloque su código en una ubicación conocida ( site-packages
o /var/opt/udi
o algo) separada de sus datos. Utilice un buen control de versión en su código para asegurarse de que tiene las versiones actual y anterior separadas para que pueda recurrir a versiones anteriores y probar futuras versiones.
En pocas palabras: no mezcle código y datos.
Los datos son preciosos. El código viene y va.
Proporcione el directorio de trabajo como un valor de argumento de línea de comandos. Puede proporcionar un valor predeterminado como variable de entorno. No lo deduzca (o adivine)
Haga que sea un valor de argumento obligatorio y haga esto.
import sys
import os
working= os.environ.get("WORKING_DIRECTORY","/some/default")
if len(sys.argv) > 1: working = sys.argv[1]
os.chdir( working )
No "asuma" un directorio basado en la ubicación de su software. No funcionará bien en el largo plazo.
Puede obtener una versión más corta utilizando sys.path[0]
.
os.chdir(sys.path[0])
Desde http://docs.python.org/library/sys.html#sys.path
Como se inicializó al inicio del programa, el primer elemento de esta lista, la
path[0]
, es el directorio que contiene la secuencia de comandos que se utilizó para invocar al intérprete de Python.