Onde posso definir variáveis ??de ambiente que crontab vai usar?
-
19-09-2019 - |
Pergunta
Eu tenho um crontab a cada hora. O usuário que executa tem ambiente variabless na .bash_profile
que o trabalho quando o usuário executa o trabalho a partir do terminal, no entanto, obviamente, estes não são apanhados por crontab quando ele é executado.
Eu tentei colocá-los em .profile
e .bashrc
mas eles ainda não parecem ter pego. Alguém sabe onde eu posso colocar ambiente vars que crontab pode pegar?
Solução
Have 'cron' executar um shell script que define o ambiente antes de executar o comando.
Sempre.
# @(#)$Id: crontab,v 4.2 2007/09/17 02:41:00 jleffler Exp $
# Crontab file for Home Directory for Jonathan Leffler (JL)
#-----------------------------------------------------------------------------
#Min Hour Day Month Weekday Command
#-----------------------------------------------------------------------------
0 * * * * /usr/bin/ksh /work1/jleffler/bin/Cron/hourly
1 1 * * * /usr/bin/ksh /work1/jleffler/bin/Cron/daily
23 1 * * 1-5 /usr/bin/ksh /work1/jleffler/bin/Cron/weekday
2 3 * * 0 /usr/bin/ksh /work1/jleffler/bin/Cron/weekly
21 3 1 * * /usr/bin/ksh /work1/jleffler/bin/Cron/monthly
Os scripts em ~ / bin / Cron são todos os links para um único script, 'runcron', que se parece com:
: "$Id: runcron.sh,v 2.1 2001/02/27 00:53:22 jleffler Exp $"
#
# Commands to be performed by Cron (no debugging options)
# Set environment -- not done by cron (usually switches HOME)
. $HOME/.cronfile
base=`basename $0`
cmd=${REAL_HOME:-/real/home}/bin/$base
if [ ! -x $cmd ]
then cmd=${HOME}/bin/$base
fi
exec $cmd ${@:+"$@"}
(escrito usando um velho padrão de codificação -. Hoje em dia, eu usaria um shebang '! #' No início)
O '~ / .cronfile' é uma variação do meu perfil para uso por cron - rigorosamente não-interativo e não ecoa por uma questão de ser barulhento. Você poderia arranjar para executar o .profile e assim por diante, em vez. (O material REAL_HOME é um artefato do meu ambiente -. Você pode fingir que é o mesmo que $ HOME)
Assim, este código lê o ambiente apropriado e, em seguida, executa a versão não-Cron do comando do meu diretório home. Assim, por exemplo, o meu 'dia da semana' comando se parece com:
: "@(#)$Id: weekday.sh,v 1.10 2007/09/17 02:42:03 jleffler Exp $"
#
# Commands to be done each weekday
# Update ICSCOPE
n.updics
O comando 'diário' é mais simples:
: "@(#)$Id: daily.sh,v 1.5 1997/06/02 22:04:21 johnl Exp $"
#
# Commands to be done daily
# Nothing -- most things are done on weekdays only
exit 0
Outras dicas
Você pode definir variáveis ??de ambiente no próprio crontab durante a execução crontab -e
a partir da linha de comando.
LANG=nb_NO.UTF-8
LC_ALL=nb_NO.UTF-8
# m h dom mon dow command
* * * * * sleep 5s && echo "yo"
Este recurso está disponível apenas para determinadas implementações de cron. Ubuntu e Debian usa atualmente vixie-cron que permite que estes sejam declarados no arquivo crontab (também GNU mcron ).
Archlinux e RedHat uso cronie quais não permitir que as variáveis ??de ambiente a ser declarado e lançará erros de sintaxe na cron.log. Solução alternativa pode ser feito per-entrada:
# m h dom mon dow command
* * * * * export LC_ALL=nb_NO.UTF-8; sleep 5s && echo "yo"
Eu tenho mais uma solução para este problema:
0 5 * * * . $HOME/.profile; /path/to/command/to/run
Neste caso, ele vai pegar toda a variável de ambiente definida no seu arquivo $HOME/.profile
.
De $HOME
claro, também não está definida, você tem que substituí-lo com o caminho completo do seu $HOME
.
Configuração vars em /etc/environment
também trabalhou para mim no Ubuntu. A partir de 12.04, variáveis ??em /etc/environment
são carregados para cron.
Expandindo exemplo @carestad, que eu acho mais fácil, é para executar o script com cron e têm o ambiente no script.
No arquivo crontab -e:
SHELL=/bin/bash
*/1 * * * * $HOME/cron_job.sh
No arquivo cron_job.sh:
#!/bin/bash
source $HOME/.bash_profile
some_other_cmd
Qualquer comando após a fonte de Bash_profile terá seu ambiente como se você logado.
Se você iniciar os scripts que você está executando através de cron com:
#!/bin/bash -l
Eles devem pegar suas variáveis ??de ambiente ~/.bash_profile
Para mim, eu tinha que definir a variável de ambiente para uma aplicação PHP. I resloved-lo adicionando o seguinte código ao meu crontab.
$ sudo crontab -e
crontab:
ENVIRONMENT_VAR=production
* * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php
e dentro doSomethingWonderful.php eu poderia obter o valor de ambiente com:
<?php
echo $_SERVER['ENVIRONMENT_VAR']; # => "production"
Espero que isso ajude!
O que quer que você definir em crontab
estará disponível nas cronjobs, direta e usando as variáveis ??nos scripts.
Use-os na definição do cron
Você pode configurar crontab
para que ele define variáveis ??que então o pode Cronjob uso:
$ crontab -l
myvar="hi man"
* * * * * echo "$myvar. date is $(date)" >> /tmp/hello
Agora, os autos /tmp/hello
coisas como:
$ cat /tmp/hello
hi man. date is Thu May 12 12:10:01 CEST 2016
hi man. date is Thu May 12 12:11:01 CEST 2016
Use-os no script executado pelo cron
Você pode configurar crontab
para que ele define variáveis ??que, em seguida, os scripts podem usar:
$ crontab -l
myvar="hi man"
* * * * * /bin/bash /tmp/myscript.sh
E digamos /tmp/myscript.sh
script é assim:
echo "Now is $(date). myvar=$myvar" >> /tmp/myoutput.res
Ele gera uma exibição de arquivo /tmp/myoutput.res
:
$ cat /tmp/myoutput.res
Now is Thu May 12 12:07:01 CEST 2016. myvar=hi man
Now is Thu May 12 12:08:01 CEST 2016. myvar=hi man
...
Em vez de
0 * * * * sh /my/script.sh
Use o bash -l -c
0 * * * * bash -l -c 'sh /my/script.sh'
Expandindo @ Robert Brisita acaba de expandir-se, também, se você não quiser configurar todas as variáveis ??do perfil no script, você pode selecionar as variáveis ??para exportação no topo do script
No arquivo crontab -e:
SHELL=/bin/bash
*/1 * * * * /Path/to/script/script.sh
Em script.sh
#!/bin/bash
export JAVA_HOME=/path/to/jdk
some-other-command
Outra forma - inspirado por este esta resposta - a variáveis ??"inserir" é o seguinte (exemplo fcron):
%daily 00 12 \
set -a; \
. /path/to/file/containing/vars; \
set +a; \
/path/to/script/using/vars
De help set
:
-a variáveis ??marca que são modificados ou criados para exportação.
Usando + em vez de -. Faz com que essas bandeiras para ser desligado
Então tudo entre set -
e set +
é exportado para env
e fica disponível para outros scripts, etc. Sem usar set
as variáveis ??se sourced mas ao vivo em set
somente.
Além de que também é útil para passar variáveis ??quando um programa requer uma conta não-root para executar, mas você precisa de algumas variáveis ??dentro de ambiente que outro usuário. Abaixo está um exemplo de passar em nullmailer vars para formatar o cabeçalho do e-mail:
su -s /bin/bash -c "set -a; \
. /path/to/nullmailer-vars; \
set +a; \
/usr/sbin/logcheck" logcheck
Eu tentei a maioria das soluções fornecidas, mas nada funcionou no início. Acontece, porém, que não era as soluções que não conseguiram trabalho. Aparentemente, o meu arquivo ~/.bashrc
começa com o seguinte bloco de código:
case $- in
*i*) ;;
*) return;;
esac
Esta é basicamente uma case statement
que verifica o conjunto atual de opções no shell atual para determinar que o shell está sendo executado de forma interativa.
Se o shell acontece a ser executado de forma interativa, em seguida, ele se move para o abastecimento do arquivo ~/.bashrc
.
No entanto, em um shell invocado por cron
, a variável $-
não contém o valor i
que indica interatividade.
Portanto, o arquivo ~/.bashrc
nunca é originária totalmente. Como resultado, as variáveis ??de ambiente nunca foi definido.
Se isso acontecer a ser o seu problema, fique à vontade para comentar o bloco de código como segue e tente novamente:
# case $- in
# *i*) ;;
# *) return;;
# esac
Espero que este acaba útil
Eu estou usando Oh-my-zsh
no meu macbook então eu tentei muitas coisas para que a tarefa crontab corridas, mas finalmente, a minha solução foi antecedendo o .zshrc
antes do comando para ser executado.
*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js
Esta tarefa é executada a cada 30 minutos e usos perfil .zshrc
para executar meu comando nó.
Não se esqueça de usar o ponto antes do $HOME
var.