A execução do crontab não possui as mesmas variáveis ​​de ambiente que a execução do usuário

20

Executei meu trabalho do crontab 0 2 */1 * * /aScript >aLog.log 2>&1como um usuário 'root' e, no entanto, achei que o env é diferente do env do usuário 'root' e, portanto, estou enfrentando um comportamento de tempo de execução diferente dos meus scripts.

Uma tentativa de correção foi colocar comandos de exportação em arquivos rc.d, mas ainda não apareceu! Acabo colocando comandos de exportação no próprio aScript .

Minha pergunta é que existe uma maneira melhor de abordar esse problema? e por que o env está ausente mesmo que seja do mesmo usuário 'root'? (Eu modifico o crontab executando 'crontab -e' a partir da raiz)

Bambu
fonte
8
Cron sempre roda com um ambiente quase vazio. HOME, LOGNAME e SHELL estão definidos; e um caminho muito limitado. Se você não desejar definir todas as variáveis, poderá conseguir o sourceseu perfil (bash).
cyberx86
2
@ cyberx86: Por que não escrever isso como resposta e obter representante?
user9517 suporta GoFundMonica
2
@ Iain: representante é sempre bem-vindo - mas às vezes parece que uma resposta em uma linha não ganha o representante. Aceito plenamente que uma resposta sucinta tenha seu lugar, mas eu tenho (talvez incorretamente) usado os comentários como uma 'saída fácil' quando eu queria fornecer alguma ajuda, mas não escrevi uma explicação completa e detalhada (era 01:00. ..) No entanto, seguirei seu conselho e expandirei um pouco esse assunto e o adicionarei como resposta.
cyberx86
@ cyberx86: Melhor ter um liner correto do que incorreto ou nada.
user9517 suporta GoFundMonica

Respostas:

31

Cron sempre roda com um ambiente quase vazio. HOME, LOGNAME e SHELL estão definidos; e um caminho muito limitado. Portanto, é aconselhável usar caminhos completos para executáveis ​​e exportar todas as variáveis ​​necessárias em seu script ao usar cron.

Existem várias abordagens que você pode usar para definir suas variáveis ​​de ambiente no cron, mas todas elas definem isso em seu script.

Abordagem 1:

Defina cada variável que você precisa manualmente em seu script.

Abordagem 2:

Crie seu perfil:

. $HOME/.bash_profile(ou . $HOME/.profile)

(Você geralmente descobrirá que o arquivo acima irá originar outros arquivos (por exemplo, ~ / .bashrc -> / etc / bashrc -> /etc/profile.d/*) - caso contrário, você também poderá obtê-los.)

Abordagem 3:

Salve suas variáveis ​​de ambiente em um arquivo (execute como o usuário desejado):

env > /path/to/my_env.sh

Em seguida, importe via seu script cron:

env - `cat /path/to/my_env.sh` /bin/sh

Abordagem 4:

Em alguns casos, você pode definir variáveis ​​cron globais em /etc/default/cron. No entanto, há um elemento de risco, pois eles serão definidos para todos os trabalhos cron.

cyberx86
fonte
A abordagem 2 é melhor para servidores em que você tem coisas sensíveis que não devem atingir o disco em ambientes envios - senhas, chaves API etc.
ap
A abordagem 4 funcionou para mim no ambiente do docker, onde o mecanismo do docker define vários ambientes. Para que isso funcionasse, tive que salvar meu env no ponto de entrada do docker. A solução completa está aqui: github.com/rayyanqcri/swarm-scheduler
Hammady
Você poderia elaborar a abordagem 3 para mim? Quando tento importá-lo, recebo bash: SHELL=/bin/bash: No such file
#
1

Cron cria seu próprio shell com o uso especificado através do qual será executado.

Portanto, se você deseja manter a mesma variável do seu usuário, tente executá-la com seu próprio usuário, em vez de raiz ou qualquer outro usuário.

Ou

A melhor maneira é exportar essas variáveis ​​em seu próprio script.

Farhan
fonte
1

No RedHat CentOS, você pode definir /etc/rc.d/init.d/functions o caminho padrão para definir permanentemente. /etc/rc.d/crond chama funções quando é iniciado.

user215450
fonte
0

Eu tive um problema semelhante na minha AWS. Descobri assim

which python3

me deu a /usr/bin/local/python3localização

e depois

. $HOME/.profile; /usr/local/bin/python3 /home/ubuntu/your_script.py
Al Po
fonte