Python: Alterar os scripts diretório de trabalho para próprio diretório do script

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

  •  07-07-2019
  •  | 
  •  

Pergunta

Eu corro um shell python de crontab a cada minuto:

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

/home/udi/foo tem alguns subdiretórios necessários, como /home/udi/foo/log e /home/udi/foo/config, que /home/udi/foo/bar.py se refere.

O problema é que crontab executa o script a partir de um diretório de trabalho diferente, de modo a tentar ./log/bar.log abertura falhar.

Existe uma boa maneira de dizer ao script para alterar o diretório de trabalho para próprio diretório do script? Eu faria fantasia uma solução que iria trabalhar para qualquer local roteiro, em vez de dizer explicitamente o script onde está.

EDIT:

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

Foi a solução elegante mais compacto. Obrigado por suas respostas e explicações!

Foi útil?

Solução

Isto irá alterar o diretório de trabalho atual para modo que os caminhos relativos abertura, será trabalhar:

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

No entanto, você perguntou como para se transformar em qualquer diretório seu script Python está localizado, mesmo se você não sabe o diretório que será quando você está escrevendo o script. Para fazer isso, você pode usar as funções os.path:

import os

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

Isso leva o nome do arquivo do seu script, converte-lo para um caminho absoluto, em seguida, extrai o diretório desse caminho, em seguida, muda para o diretório.

Outras dicas

Você pode obter uma versão mais curta usando sys.path[0].

os.chdir(sys.path[0])

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

Como inicializado na inicialização do programa, o primeiro item da lista, path[0], é o diretório que contém o script que foi usado para invocar o interpretador Python

Não faça isso.

Seus scripts e seus dados não devem ser trituradas em um diretório grande. Coloque seu código em algum local conhecido (site-packages ou /var/opt/udi ou algo assim) separar de seus dados. Use bom controle de versão em seu código para ter certeza de que você tem as versões atuais e anteriores separados uns dos outros, assim você pode cair de volta para versões anteriores e futuras versões de teste.

A linha inferior:. Do código não se misturam e os dados

Os dados é precioso. Código vem e vai.

Forneça o diretório de trabalho como um valor de argumento de linha de comando. Você pode fornecer um padrão como uma variável de ambiente. Não deduzi-la (ou adivinhar-lo)

Faça-lhe um valor argumento necessário e fazer isso.

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

Do not "assumir" um diretório com base na localização do seu software. Não vai funcionar bem no longo prazo.

Alterar seu comando crontab para

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

O (...) inicia uma sub-shell que seus executa crond como um único comando. O || exit 1 faz com que seu cronjob a falhar no caso de que o diretório não está disponível.

Embora as outras soluções podem ser mais elegante no longo prazo para seus scripts específicos, meu exemplo poderia ainda ser útil em casos em que você não pode modificar o programa ou comando que você deseja executar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top