
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, PATH
no 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/.bashrc
mi start.sh
script ya que creo que ahí es donde PATH
se 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 ubuntu
y 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_profile
si 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
~/.bashrc
es 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 -e
y agregue antes de todas las demás líneas.SHELL=/bin/bash
Esto 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/.bashrc
no 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,
PATH
todaví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 PATH
tendrí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
...