¿Ejecutar script en un shell no interactivo?

17

Tengo un trabajo cron que ejecuta un script. Cuando ejecuto el script a través de un shell interactivo (ssh'ed to bash) funciona bien. Cuando el script se ejecuta solo a través de cron, falla.

Mi conjetura es que está usando algunas de las variables ambientales establecidas en el shell interactivo. Voy a solucionar el script y eliminarlos.

Después de hacer cambios, sé que podría poner en cola el script en cron para que se ejecute como lo haría normalmente, pero ¿hay alguna manera de que pueda ejecutar el script desde la línea de comando, pero decirle que se ejecute como lo haría desde cron? es decir, en un entorno no interactivo?

cwd
fuente
Relacionado y, por lo tanto, posiblemente útil: "¿Cómo obtener un entorno limpio en un shell ksh?" ver especialmente la respuesta de @Gilles con respecto unset.
Sr_
1
Desde el enlace de @ sr_, miré hacia arriba envy es posible que desee probar env -i ./my-script.sh. Además, ¿recibes un mensaje de error?
Kevin
¿Qué implementación cron estás usando?
rozcietrzewiacz
@kevin: votaré si respondes con eso.
cwd

Respuestas:

12

Las principales diferencias entre ejecutar un comando desde cron y ejecutar en la línea de comando son:

  • cron probablemente esté usando un shell diferente (generalmente /bin/sh);
  • cron definitivamente se está ejecutando en un entorno pequeño (cuáles dependen de la implementación de cron, así que revise la página cron(8)o crontab(5)man; generalmente solo hay HOME, tal SHELLvez LOGNAME, tal vez USER, y un pequeño PATH);
  • cron trata al %personaje especialmente (se convierte en una nueva línea);
  • Los trabajos cron se ejecutan sin un terminal o entorno gráfico.

La siguiente invocación ejecutará el fragmento de shell casi como si fuera invocado desde cron. Supongo que el fragmento no contiene los caracteres 'o %.

env - HOME="$HOME" USER="$USER" PATH=/usr/bin:/bin /bin/sh -c 'shell snippet' </dev/null >job.log 2>&1

Consulte también la ejecución de un script sh desde el cron , que podría ayudarlo a resolver su problema.

Gilles 'SO- deja de ser malvado'
fuente
Hola @Giles, solo pensé en algo, ¿ejecutar un script sudo -u user /path/to/scripttambién sería una forma de ejecutarlo sin ninguna variable establecida?
cwd
@cwd No, generalmente no. sudoborra algunas variables y establece otras en un valor conocido, pero eso depende de cómo esté configurado. A menudo se configura para conservar la configuración regional y TERM, por ejemplo.
Gilles 'SO- deja de ser malvado'
2

Desde el enlace de @ sr_ ( ¿Cómo obtener un entorno limpio en un shell ksh? ), Busqué env, y es posible que desee probar esto:

env -i ./my-script.sh
Kevin
fuente
Esto funcionó bien para mí, aunque la respuesta de @Gilles también es muy buena.
cwd
@cwd: No funciona para mí: echo -e '#!/bin/bash -i\necho interactive $-' > ~/test.sh && chmod +x ~/test.sh && env -i ~/test.shsalidas interactive himB.
Alix Axel
1

Te sugiero que uses rutas absolutas para tus scripts cuando lo pongas en cron y lo uses en cualquier otro lugar y para todos y cada uno de los comandos de linux utilizados en él, ¡mejor declaralos como variables y úsalo!

Gaumire
fuente
si. pero por supuesto.
cwd
0

Cron no necesariamente usa el mismo shell que estás usando. cheque:

cat /etc/crontab |grep SHELL

Para determinar el shell e intentar la ejecución de su script allí, ¿funciona? Esta es una causa común de problemas para muchas personas que agregan scripts a cron.

Si este es el problema, puede agregar "bash" al comienzo de su script en cron para forzar que este script se ejecute en bash. Si esto no resuelve el problema, avíseme y profundizaré un poco más.

Mate
fuente
0

Si desea ignorar algunas preguntas interactivas proporcionadas por algún script, puede intentar:

yes | your_command

O yes "n"si desea No todas las preguntas.

Mando:

sí: ser reiteradamente afirmativo sí produce improperios o, por defecto, 'y', para siempre.

kenorb
fuente
0

Para ejecutar su script en un shell no interactivo (sin tener en cuenta los detalles de cron), puede hacerlo a través de ssh.

Prueba si realmente terminas en un shell no interactivo:

> ssh someuser@somehost tty
not a tty

Ejecute el script en un shell no interactivo:

> ssh someuser@somehost /tmp/myscript.sh
dokaspar
fuente