hacer que Cron se ejecute en el mismo entorno que con el inicio de sesión ssh

hacer que Cron se ejecute en el mismo entorno que con el inicio de sesión ssh

Tengo un script que funciona bien cuando accedo por ssh a mi instancia EC2 de Ubuntu y lo ejecuto (como usuario ubuntu)

Quiero que esto suceda cuando se inicie el servidor, así que lo agregué al cron como:

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

Sin embargo, cuando cron lo ejecuta, PATHno es lo mismo y algunos comandos fallan porque los archivos binarios no están cargados:

$ 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'

Intenté agregar source /home/ubuntu/.bashrcmi start.shscript ya que creo que ahí es donde PATHse construye, al menos parcialmente, pero eso no parece cambiar mucho:

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

También verifiqué que Cron se ejecuta como ubuntuy no root, lo que parece ser el caso desde que edité los trabajos cron que iniciaban sesión comoubuntu

¿Existe una manera fácil de ejecutar cron en el mismo entorno que obtengo después de iniciar sesión en mi servidor mediante ssh?

Respuesta1

Normalmente, las variables de entorno deben definirse en ~/.profile, o ~/.bash_profilesi este archivo existe, su shell de inicio de sesión es bash. Entonces cargue este archivo desde el trabajo cron.

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

~/.bashrces solo para personalizaciones interactivas, por lo que no debe cargarlo de forma no interactiva y, por lo general, no funcionará de todos modos. Si tiene definiciones de variables de entorno en .bashrc, solucione ese problema primero.

Otro lugar para configurar variables de entorno es ~/.pam_environment, si desea que la variable tenga un valor constante (no puede ejecutar comandos de shell en este archivo).

Ver¿Cuál es la mejor forma independiente de distribución/shell para configurar variables de entorno?,¿Diferencia entre Shell de inicio de sesión y Shell sin inicio de sesión?y¿Existe un archivo equivalente ".bashrc" leído por todos los shells?para obtener más información sobre los archivos de inicio del shell.

Respuesta2

cron normalmente se ejecuta con sh, no con bash, estos tienen perfiles diferentes.

intente ejecutar el cron individual en bash, si tiene varias variables de entorno personalizadas, siempre puede env>/file, source/file en el cron.

Respuesta3

Resolví mi problema como:

  • run $ crontab -ey agregue antes de todas las demás líneas. SHELL=/bin/bashEsto obligará a cron a usar bash. Hayalternativassi quieres hacer eso solo para un comando
  • my .bashrc, que era el valor predeterminado que se obtiene en una instancia de AWS EC2 ubuntu, tenía esas líneas:

.

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

hacerlo source /home/ubuntu/.bashrcno haría nada en el trabajo cron. Parece tener un propósito, así que no lo eliminé por completo, sino que lo reemplacé 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

lo que me permitió poner una señal para evitar este regreso anticipado.

  • Finalmente, por algunas razones, PATHtodavía no se actualizó correctamente. Podría solucionarlo haciendo:

.

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

No estoy 100% seguro de lo que eso hace :) pero al final tengo lo mismo que PATHtendría al iniciar sesión con ssh.

Así que finalmente:

crontab:

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

~/.bashrc: el reemplazo anterior

~/start.sh:

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

información relacionada