Python: Alterar os scripts diretório de trabalho para próprio diretório do script
-
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!
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.