fazer com que o Cron seja executado no mesmo ambiente que eu recebo com o login ssh

fazer com que o Cron seja executado no mesmo ambiente que eu recebo com o login ssh

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

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

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

No entanto, quando o cron é executado, PATHnã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'

Tentei adicionar source /home/ubuntu/.bashrcmeu start.shscript porque acredito que é onde ele PATHé construído, 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 ubuntue não root, o que parece ser o caso, já que editei os cron jobs sendo logados comoubuntu

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

Responder1

Normalmente as variáveis ​​de ambiente devem ser definidas em ~/.profile, ou ~/.bash_profilese este arquivo existir, seu shell de login é bash. Portanto, carregue este arquivo do cron job.

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

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

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

VerQual é a melhor maneira independente de distribuição/shell para definir variáveis ​​de ambiente?,Diferença entre Shell de login e Shell sem login?eExiste um arquivo equivalente ".bashrc" lido por todos os shells?para obter mais informações sobre arquivos de inicialização do shell.

Responder2

cron normalmente é executado com sh e não com bash, eles têm perfis diferentes.

tente executar o cron individual no bash, se você tiver vários env vars personalizados, você sempre pode env>/file, source /file no cron.

Responder3

Resolvi meu problema como:

  • run $ crontab -ee add antes de todas as outras linhas. SHELL=/bin/bashIsso forçará o cron a usar o bash. Háalternativasse você quiser fazer isso apenas para um comando
  • my .bashrc, que era o padrão que você obtém em uma instância do AWS EC2 ubuntu, tinha essas linhas:

.

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

fazer isso source /home/ubuntu/.bashrcnão faria nada no cron job. Parece servir a um propósito, então não o removi completamente, mas substituí-o 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

o que me permitiu definir um sinalizador para ignorar esse retorno antecipado.

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

.

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

Não tenho 100% de certeza do que isso faz :) mas no final tenho o mesmo que PATHfaria ao fazer 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
...

informação relacionada