cron ignora variáveis definidas em “.bashrc” e “.bash_profile”

40

Eu defini a variável "SHELL" no arquivo / etc / crontab:

[martin@martin ~]$ grep SHELL /etc/crontab 
SHELL=/usr/local/bin/bash
[martin@martin ~]$ file /usr/local/bin/bash
/usr/local/bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), dynamically linked (uses shared libs), for FreeBSD 8.0 (800107), stripped
[martin@martin ~]$ 

Além disso, todos os meus scripts no arquivo / etc / crontab são iniciados sob o usuário "martin". No entanto, /home/martin/.bash_profile (para shell de login) e /home/martin/.bashrc (para shell não-registrador) contêm algumas variáveis que são ignoradas no caso de trabalho cron, mas são usados no caso de eu fazer o login na máquina através de SSH ou abrir nova sessão bash. Por que o cron ignora essas variáveis? Não é o cron simplesmente executar "/usr/local/bin/bash my-script.sh" com permissões para o usuário "martin"?

    
por Martin 14.03.2013 / 17:03

5 respostas

58

Você pode criar o arquivo que deseja na parte superior do script ou no início do trabalho para o usuário que está executando o trabalho. O comando "source" é um built-in. Você faria o mesmo se fizesse edições nesses arquivos para carregar as alterações.

* * * * * source /home/user/.bash_profile; <command>

ou

#!/bin/bash
source /home/user/.bash_profile

<commands>
    
por 14.03.2013 / 19:09
19

Porque não é um shell interativo. O mesmo acontece quando você abre alguns terminais.

Dê uma olhada nesta questão: Qual é o arquivo .bashrc? | Superusuário

E também neste:

Qual é a diferença entre .bashrc, .bash_profile e .meio Ambiente? | Estouro de pilha

Diferentes scripts são acionados dependendo se a conexão é um shell de login (ou não), um shell interativo (ou não) ou ambos.

Se você quiser fazer o bashrc, precisará fazer essa alteração:

When Bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute. Bash behaves as if the following command were executed:

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi 

but the value of the PATH variable is not used to search for the file name.

As noted above, if a non-interactive shell is invoked with the --login option, Bash attempts to read and execute commands from the login shell startup files.

Fonte: Arquivos de inicialização do Bash | Manual de Referência do Bash | gnu.org

    
por 14.03.2013 / 17:15
7

Você pode não conseguir executar source se o shell sh estiver sendo usado. Isso pode ser alterado adicionando a seguinte linha no seu crontab:

SHELL=/bin/bash
* * * * * source "/root/.bashrc"; <command>

Você também pode especificar o ambiente:

BASH_ENV="/root/.bashrc"
* * * * * <command>

ou você pode usar seu local /home/user/.bashrc se for uma tarefa cron do usuário (por exemplo, crontab -e ).

Observe que .bash_profile pode substituir .bashrc , se existir.

Crédito: Como alterar o shell do cron (sh para bash )?

    
por 03.05.2017 / 09:37
0

bash age de forma diferente, seja um shell ou uma linguagem de programação (como perl ou python ).

Por design, essas configurações em ~/.bash_profile , ~/.bashrc , etc. são para os usuários definirem as configurações quando bash reproduzir o roll de um shell (shell de login, shell interrativo). Pense no ambiente que você tem em um xterm (shell interrativo) ou em ssh sessions (shell de login) ou em consoles (shell de login).

Por outro lado, bash também é uma poderosa linguagem de programação - pense em muitos scripts para gerenciar serviços em systemd - o que requer um estilo diferente de trabalho. Por exemplo, quando um desenvolvedor escreve um script do sistema ou um programa bash , ele / ela provavelmente não irá originar o ~/.bash_profile definido pelo usuário automaticamente. É um programa normal, não um shell. Um programa normal (incluindo programas bash ) naturalmente configuraria a configuração em um ambiente de trabalho atual (shell), mas não os definiria .

Se escrevermos um programa para cron em bash - é apenas por acaso que está escrito em bash ; na verdade, podemos escrevê-lo em python ou perl ou qualquer outra linguagem de programação - então, podemos ter uma opção para fontes bash ' ~/.bash_profile (leia: configuração do shell do usuário, que acontece seja a mesma linguagem da sua linguagem de programação):

[ -f /home/user/.bash_profile ] && . /home/user/.bash_profile

No entanto, e se esse usuário em particular não usar bash como seu shell? Ele / ela pode usar zsh , 'ksh , fish', etc. Então, essa prática realmente não funciona ao escrever programas para uso público.

Então, você pode pesquisar ~/.bash_profile se achar que funciona. Mas, aqui, não é sobre se somos capazes de criar um arquivo, é sobre como as coisas devem funcionar no sistema: o conceito de design . Resumindo: devemos ver bash como algo com 2 rolos: linguagem de shell e programação . Então tudo ficará claro, mais fácil de entender.

    
por 19.01.2018 / 17:15
-1

Minha maneira de lidar com isso foi:

1) Colocando minhas variáveis no (final de) ~/.profile :

myVarInDotProfile="someValue"

2) Criando um script Bash para minhas tarefas cron (diárias) ( ~/cronDaily.sh ) contendo meus comandos, além de fontes repetitivas de ~/.profle :

source ~/.profile
command ${myVarInDotProfile}/

3) agendando a execução do meu script a partir de crontab , para ser executada diariamente:

0 0 * * * bash ~/cronDaily.sh

Minha variável não foi ignorada e os comandos foram executados com sucesso.

Alguns podem dizer que o sourcing intenso de ~/.profile é problemático. No meu caso particular, não vejo porque é um problema, mas aconselho a considerar a criação de um arquivo dedicado para isso.

Em geral, pode haver uma maneira melhor para isso, mas foi o que funcionou para mim depois de muita dor e explica o princípio de que, a partir do Bash 4.3.46, você não pode criar um arquivo a partir de crontab .

    
por 19.01.2018 / 18:51

Tags