obter Cron para executar no mesmo ambiente que eu recebo com o login ssh

3

Eu tenho um script que roda bem quando eu ssh para a minha instância do EC2 do Ubuntu e o executo (como o usuário ubuntu )

Eu quero que isso aconteça quando o servidor inicializar, então eu adicionei ao cron como:

@reboot sleep 10 && /home/ubuntu/start.sh

No entanto, quando o cron o executa, o PATH não é o mesmo e alguns comandos falham porque os binários não são carregados:

$ echo $PATH
/home/ubuntu/.nvm/versions/node/v4.2.6/bin:/home/ubuntu/bin:/home/ubuntu/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

# in start.sh
echo "path $PATH" >> start.logs
# will log 'path /usr/bin:/bin'

Eu tentei adicionar source /home/ubuntu/.bashrc no meu script start.sh , pois acredito que é onde o PATH é criado, pelo menos parcialmente, mas isso não parece mudar muito:

# in start.sh
source /home/ubuntu/.bashrc
echo "path $PATH" >> start.logs
# will still log 'path /usr/bin:/bin'

Também verifiquei se o Cron é executado como ubuntu e não root , o que parece ser o caso desde que editei os trabalhos agendados sendo registrados como ubuntu

Existe uma maneira fácil de executar o cron no mesmo ambiente que obtenho após o login no meu servidor pelo ssh?

    
por Guig 05.11.2016 / 21:40

3 respostas

1

Normalmente, as variáveis de ambiente devem ser definidas em ~/.profile , ou ~/.bash_profile se esse arquivo existir, seu login shell é bash. Então, carregue este arquivo do cron job.

@reboot . ~/.profile; sleep 10 && /home/ubuntu/start.sh

~/.bashrc é somente para personalizações interativas, portanto, você não deve carregá-lo de forma não interativa e, normalmente, não funcionará de qualquer maneira. Se você tiver definições de variáveis de ambiente em .bashrc , corrija essa confusão primeiro.

Outro local para definir variáveis de ambiente é ~/.pam_environment , se você quiser a variável com um valor constante (você não pode executar comandos shell neste arquivo).

Veja Qual é a melhor maneira de distribuir as variáveis de ambiente? , Diferença entre o Shell de Login e o Shell de Não Login? e Existe um arquivo equivalente" .bashrc "lido por todos os shells? para mais informações sobre arquivos de inicialização do shell.

    
por 07.11.2016 / 01:44
0

cron normalmente é executado com sh não bash, eles possuem perfis diferentes.

tente rodar o cron individual no bash, se você tiver um número de custom env vars você pode sempre env > / file, source / file no cron.

    
por 05.11.2016 / 22:38
0

Eu resolvi meu problema como:

  • execute $ crontab -e e adicione antes de todas as outras linhas SHELL=/bin/bash Isso forçará o cron a usar o bash. Existem alternativas se você quiser fazer isso apenas para um comando
  • my .bashrc , que era o padrão que você recebe em uma instância do AWS EC2 Ubuntu, tinha essas linhas:

.

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

, portanto, source /home/ubuntu/.bashrc não faria nada no cron job. Parece servir a um propósito, então eu não o removi completamente, mas substituí-lo por:

# If not running interactively, don't do anything
if [ -z ${RUN_BASHRC+x} ]; then
  echo "might return";
else
  case $- in
      *i*) ;;
        *) return;;
  esac
fi

que me permite definir um sinalizador para ignorar esse retorno antecipado.

  • Finalmente, por alguns motivos, o PATH ainda não foi atualizado corretamente. Eu poderia consertar fazendo:

.

ADDITIONAL_PATH=$(sudo -Hiu ubuntu env | grep -oP "^PATH=\K.*")
PATH=$ADDITIONAL_PATH:$PATH

Eu não tenho 100% de certeza do que isso faz :) mas no final eu tenho o mesmo PATH que eu tinha com o login com ssh.

Então, finalmente:

crontab:

SHELL=/bin/bash
@reboot RUN_BASHRC=1 /home/ubuntu/startup.sh >> /home/ubuntu/cron-startup.logs

~/.bashrc : a substituição acima

~/start.sh :

#!/bin/bash
ADDITIONAL_PATH=$(sudo -Hiu ubuntu env | grep -oP "^PATH=\K.*")
PATH=$ADDITIONAL_PATH:$PATH
...
    
por 06.11.2016 / 01:28