Como posso executar um comando cron com variáveis ambientais existentes?

93

Como posso executar um comando cron com variáveis ambientais existentes?

Se eu estiver em um prompt do shell, posso digitar echo $ORACLE_HOME e obter um caminho. Essa é uma das minhas variáveis ambientais que é definida no meu ~/.profile . No entanto, parece que ~/.profile não é carregado em scripts do cron e, portanto, meus scripts falham porque a variável $ORACLE_HOME não está definida.

Em esta pergunta o autor menciona a criação de um perfil ~/.cronfile que configura variáveis para o cron e, em seguida, ele faz uma solução para carregar todos os seus comandos do cron em scripts que ele mantém em seu diretório ~/Cron . Um arquivo como ~/.cronfile parece uma boa ideia, mas o resto da resposta parece um pouco incômodo e eu esperava que alguém pudesse me dizer uma maneira mais fácil de obter o mesmo resultado.

Suponho que no início dos meus scripts eu poderia adicionar algo como source ~/.profile , mas parece que poderia ser redundante.

Então, como posso fazer meus scripts cron carregar as variáveis do meu perfil de shell interativo?

    
por cwd 21.12.2011 / 05:40

11 respostas

122

No crontab, antes de você mandar, adicione . $HOME/.profile . Por exemplo:

0 5 * * * . $HOME/.profile; /path/to/command/to/run

Cron não sabe nada sobre o seu shell; é iniciado pelo sistema, por isso tem um ambiente mínimo. Se você quer alguma coisa, você precisa ter isso em si mesmo.

    
por 21.12.2011 / 05:56
33

Outra opção, que acho mais fácil, é executar o script com o cron e ter 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 origem do .bash_profile terá seu ambiente como se você estivesse logado.

    
por 06.09.2013 / 00:36
15

Outra opção, que eu acho mais fácil, é rodar o script com o cron e informar ao bash o login (daí usando /etc/profile.d/... environment definitions)

Em crontab -e file:

*/1 * * * * bash -l -c './cron_job.sh'
*/1 * * * * bash -l -c 'php -f ./cron_job.php'

Qualquer comando após a origem de .bash_profile terá seu ambiente como se você tivesse efetuado login.

    
por 02.10.2014 / 21:41
9

Má ideia. A prática geral é definir especificamente todas as variáveis ambientais necessárias em um script que deve ser executado a partir de uma tarefa cron.

    
por 21.12.2011 / 05:57
2

Esta sintaxe definitivamente ajuda você. Eu não entendo a sintaxe, mas funciona. A Oracle usa essa sintaxe ao implantar o Oracle Configuration Manager para crontab, portanto, acredito que essa seja a solução correta.

0 5 * * * SOME_ENV_VAR=some_value some_command some_parameters
    
por 10.07.2013 / 12:30
1

A solução, que funcionou para mim, é descrita aqui .

Você cria um script de wrapper, que chama . ~/.cronfile e, em seguida, faz as coisas desejadas. Este script é iniciado pelo cron.

Em ~/.cronfile , você especifica o ambiente para seus trabalhos agendados.

    
por 08.02.2013 / 07:08
1

Adicionar

BASH_ENV=/home/user/.profile

para o crontab. Consulte Como garantir a disponibilidade de $ BASH_ENV

    
por 18.10.2015 / 19:39
1

Em vez de definir o perfil, o que me ajudou foi definir o PATH . Alguns dos comandos não estavam disponíveis em meus scripts cron, pois o PATH é diferente.

ENVIRONMENT=prod
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
*/30 * * * * /opt/myscript1.sh
*/30 * * * * /opt/myscript2.sh
*/30 * * * * /opt/myscript3.sh

Definir PATH com o caminho dos comandos me ajudou. Melhor ainda se você puder usar um modelo e detemplatize mais tarde,

ENVIRONMENT={{ENVIRONMENT}}
PATH={{PATH}}
*/30 * * * * /opt/myscript1.sh
*/30 * * * * /opt/myscript2.sh
*/30 * * * * /opt/myscript3.sh

A passagem de variáveis para cada item parece confusa.

    
por 27.04.2018 / 10:57
1

Recentemente, deparei com um caso em que eu tinha que executar o cronjob geral como root, mas, ao mesmo tempo, tinha que executar um subcomando como um usuário diferente (o que exigia o fornecimento do ambiente desse usuário). Eu fui com a seguinte abordagem:

# m  h  dom  mon  dow  user  command
*/5  *   *    *    *   root  (sudo -i -u <the user> command-to-be-run-as-user) && command-to-be-run-as-root

A parte crucial é o argumento -i que está sendo passado para sudo , que executará o comando fornecido em um shell de login separado (o que, por sua vez, significa que os dotfiles do usuário serão originados).

PS: observe que a coluna user está disponível apenas nos arquivos /etc/crontab e /etc/cron.d/* .

    
por 16.05.2018 / 02:16
0

Sim, você pode usar "soluções conhecidas" (algumas das quais foram listadas). Esta é outra maneira de dizer que todo mundo sabe que é uma porcaria, apesar de algumas pessoas se referirem a isso como um "recurso de segurança", porque eles gastaram pelo menos tanta tropeçante nessa falha quanto você, e gostariam de pensar que o tempo perdido não foi em vão. É o equivalente do cron do teclado QWERTY.

Eu suspeito que o motivo original pode ter sido para o desempenho, de modo que os scripts executados uma vez por minuto não gastariam tempo para ler scripts rc. Também originalmente o cron não era realmente configurável, então um padrão era realmente a única opção.

Não há segurança adicional por não ter alguma configuração ou método simples para que o cron possa apenas assumir o ambiente do seu shell interativo em vez de os usuários terem que executar uma ginástica de shell estúpida. Em uma máquina moderna, geralmente não há ganho de desempenho perceptível, a menos que você tenha uma grande quantidade de tarefas em execução a cada minuto.

Falha na cultura Unix. Na minha humilde opinião. : -)

    
por 26.07.2013 / 03:44
-1

eu coloquei. ~/.dbus/session-bus/* no topo do meu script desejado:)

    
por 20.09.2014 / 17:18