Como simular o ambiente o cron executa um script com?

Eu normalmente tenho vários problemas com a forma como o cron executa scripts, pois eles normalmente não têm a configuração do meu ambiente. Existe uma maneira de invocar o bash (?) Da mesma forma que o cron faz para que eu possa testar os scripts antes de instalá-los?

Adicione isto ao seu cron:

30 08 * * * env > ~/cronenv 

Depois que ele for executado, faça isso:

 env - `cat ~/cronenv` /bin/sh 

Isso pressupõe que o seu cron execute / bin / sh, que é o padrão, independentemente do shell padrão do usuário.

O Cron fornece apenas este ambiente por padrão:

  • Diretório inicial do usuário HOME
  • LOGNAME usuário de LOGNAME
  • PATH=/usr/bin:/usr/sbin
  • SHELL=/usr/bin/sh

Se você precisar de mais, você pode criar um script onde você define seu ambiente antes da tabela de agendamento no crontab.

Algumas abordagens:

  1. Exportar cron env e fonte dele:

    Adicionar

     * * * * * env > ~/cronenv 

    para o seu crontab, deixe-o rodar uma vez, desligue-o e execute

     env - `cat ~/cronenv` /bin/sh 

    E você está agora dentro de uma session sh que tem o ambiente do cron

  2. Traga seu ambiente para o cron

    Você poderia pular o exercício acima e apenas fazer um . ~/.profile . ~/.profile na frente do seu cron job, por exemplo

     * * * * * . ~/.profile; your_command 
  3. Use a canvas

    Acima de duas soluções ainda falham em fornecer um ambiente conectado a uma session X em execução, com access a dbus etc. Por exemplo, no Ubuntu, nmcli (Network Manager) funcionará em duas abordagens acima, mas ainda falhará no cron.

     * * * * * /usr/bin/screen -dm 

    Adicione a linha acima ao cron, deixe-a rodar uma vez, desligue-a novamente. Conecte-se à sua session de canvas (canvas -r). Se você está verificando a session de canvas foi criada (com ps ) estar ciente de que eles são, por vezes, em maiúsculas (por exemplo, ps | grep SCREEN )

    Agora, mesmo nmcli e similares falharão.

Você pode correr:

 env - your_command arguments 

Isto irá executar seu_command com ambiente vazio.

Dependendo do shell da conta

 sudo su env -i /bin/sh 

ou

 sudo su env -i /bin/bash --noprofile --norc 

http://matthew.mceachen.us/blog/howto-simulate-the-cron-environment-1018.html

Respondendo seis anos depois: o problema de incompatibilidade do ambiente é um dos problemas resolvidos pelos “timeres” do sistema como substituto do cron. Se você executar o “serviço” systemd da CLI ou via cron, ele receberá exatamente o mesmo ambiente, evitando o problema de incompatibilidade de ambiente.

O problema mais comum para fazer com que as tarefas do cron falhem quando passam manualmente é o $PATH padrão restritivo definido pelo cron, que é isso no Ubuntu 16.04:

 "/usr/bin:/bin" 

Em contraste, o padrão $PATH definido pelo systemd no Ubuntu 16.04 é:

 "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 

Portanto, há uma chance maior de que um timer do sistema encontre um binário sem mais problemas.

A desvantagem dos timers do systemd é que há um pouco mais de tempo para configurá-los. Primeiro, você cria um arquivo “service” para definir o que deseja executar e um arquivo “timer” para definir o cronograma para executá-lo e, por fim, “ativar” o cronômetro para ativá-lo.

Crie uma tarefa cron que execute env e redirecione o stdout para um arquivo. Use o arquivo ao lado de “env -” para criar o mesmo ambiente que um cron job.

Não esqueça que desde que o pai do cron é init, ele roda programas sem um terminal de controle. Você pode simular isso com uma ferramenta como esta:

http://libslack.org/daemon/

Por padrão, o cron executa suas tarefas usando qualquer idéia de sh do seu sistema. Este poderia ser o shell Bourne real ou dash , ash , ksh ou bash (ou outro) symlinked para sh (e como resultado executando no modo POSIX).

A melhor coisa a fazer é garantir que seus scripts tenham o que precisam e que nada seja fornecido para eles. Portanto, você deve usar especificações de diretório completas e definir variables ​​de ambiente, como $PATH .

Outra forma simples que encontrei (mas pode ser propenso a erros, ainda estou testando) é fornecer os arquivos de perfil do usuário antes do seu comando.

Editando um script /etc/cron.d/:

 * * * * * user1 comand-that-needs-env-vars 

Se transformaria em:

 * * * * * user1 source ~/.bash_profile; source ~/.bashrc; comand-that-needs-env-vars 

Sujo, mas fez o trabalho para mim. Existe uma maneira de simular um login? Apenas um comando que você poderia executar? bash --login não funcionou. Parece que seria o melhor caminho a percorrer.

EDIT: Esta parece ser uma solução sólida: http://www.epicserve.com/blog/2012/feb/7/my-notes-cron-directory-etccrond-ubuntu-1110/

 * * * * * root su --session-command="comand-that-needs-env-vars" user1 -l 

Answer https://stackoverflow.com/a/2546509/5593430 mostra como obter o ambiente cron e usá-lo para o seu script. Mas esteja ciente de que o ambiente pode ser diferente dependendo do arquivo crontab que você usa. Eu criei três inputs cron diferentes para salvar o ambiente via env > log . Estes são os resultados em um Amazon Linux 4.4.35-33.55.amzn1.x86_64.

1. Global / etc / crontab com usuário root

 MAILTO=root SHELL=/bin/bash USER=root PATH=/sbin:/bin:/usr/sbin:/usr/bin PWD=/ LANG=en_US.UTF-8 SHLVL=1 HOME=/ LOGNAME=root _=/bin/env 

2. Usuário crontab de raiz ( crontab -e )

 SHELL=/bin/sh USER=root PATH=/usr/bin:/bin PWD=/root LANG=en_US.UTF-8 SHLVL=1 HOME=/root LOGNAME=root _=/usr/bin/env 

3. Script em /etc/cron.hourly/

 MAILTO=root SHELL=/bin/bash USER=root PATH=/sbin:/bin:/usr/sbin:/usr/bin _=/bin/env PWD=/ LANG=en_US.UTF-8 SHLVL=3 HOME=/ LOGNAME=root 

Mais importante, o PATH , o PWD e o HOME diferem. Certifique-se de definir estes em seus scripts cron para confiar em um ambiente estável.

Eu não acredito que haja; a única maneira que conheço para testar um cron job é configurá-lo para executar um ou dois minutos no futuro e depois esperar.