¿Por qué los scripts de crontab no funcionan?

Frecuentemente, crontab los scripts no se ejecutan según lo programado o como se esperaba. Hay numerosas razones para ello:

  1. notación crontab incorrecta
  2. problema de permisos
  3. variables de entorno

Esta wiki de la comunidad tiene como objetivo agregar las principales razones de crontab los scripts no se ejecutan como se esperaba. Escriba cada razón en una respuesta separada.

Incluya una razón por respuesta, detalles sobre por qué no se ejecuta , y corrija por esa razón.

Escriba solo problemas específicos de cron, por ejemplo, comandos que se ejecutan como se esperaba desde el shell pero se ejecutan erróneamente por cron.

Ambiente diferente

Cron pasa un conjunto mínimo de variables de entorno a sus trabajos. Para ver la diferencia, agregue un trabajo ficticio como este:

>* * * * * env /tmp/env.salida

Espera /tmp/env.output para crearlo, vuelva a quitar el trabajo. Ahora compare el contenido de /tmp/env.output con la salida de env ejecute en su terminal habitual.

Un "problema" común aquí es el PATH la variable de entorno es diferente. Tal vez su script cron use el comando somecommand encontrado en /opt/someApp/bin que has añadido a PATH en /etc/environment? cron ignora PATH de ese archivo, así que corriendo somecommand de su script fallará cuando se ejecute con cron, pero funcionará cuando se ejecute en una terminal. Vale la pena señalar que las variables de /etc/environment se pasará a los trabajos cron, pero no a las variables que cron establece específicamente, como PATH.

Para evitar eso, simplemente configure su propio PATH variable en la parte superior del script. P. ej.

#!/bin/bashPATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin# rest of script follows

Algunos prefieren usar rutas absolutas a todos los comandos en su lugar. Recomiendo en contra de eso. Considere lo que sucede si desea ejecutar su script en un sistema diferente, y en ese sistema, el comando está en /opt/someAppv2.2/bin en su lugar. Tendrías que repasar todo el guión. /opt/someApp/bin con /opt/someAppv2.2/bin en lugar de simplemente hacer una pequeña edición en la primera línea del script.

También puede establecer la variable PATH en el archivo crontab, que se aplicará a todos los trabajos cron. P. ej.

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin15 1 * * * backupscript --incremental /home /root

Mi problema principal: Si olvida agregar una nueva línea al final de la crontab file. En otras palabras, el archivo crontab debe terminar con una línea vacía.

A continuación se muestra la sección relevante de las páginas de manual para este problema (man crontab luego salta al final):

   Although cron requires that each entry in a crontab end  in  a  newline   character,  neither the crontab command nor the cron daemon will detect   this error. Instead, the crontab will appear to load normally. However,   the  command  will  never  run.  The best choice is to ensure that your   crontab has a blank line at the end.   4th Berkeley Distribution      29 December 1993               CRONTAB(1)

El demonio Cron no se está ejecutando. La verdad es que metí la pata con esto hace unos meses.

Tipo:

pgrep cron 

Si no ve ningún número (es decir, el PID principal de cron), cron no se está ejecutando. sudo /etc/init.d/cron start se puede usar para iniciar cron.

EDITAR: En lugar de invocar scripts de inicio a través de /etc/init.d, utilice la utilidad de servicio, p. ej.

sudo service cron start

EDITAR: También puede usar systemctl en Linux moderno, p. ej.

sudo systemctl start cron

Los nombres de archivo de script en cron.d/, cron.daily/, cron.hourly/, sucesivamente., no debe contener punto (.), de lo contrario, las partes de ejecución las omitirán.

Piezas de repuesto (8):

   If neither the --lsbsysinit option nor the --regex option is given then   the names must consist entirely of upper and lower case  letters,  dig‐   its, underscores, and hyphens.   If  the  --lsbsysinit  option  is given, then the names must not end in   .dpkg-old  or .dpkg-dist or .dpkg-new or .dpkg-tmp, and must belong  to   one  or more of the following namespaces: the LANANA-assigned namespace   (^[a-z0-9]+$);   the   LSB   hierarchical   and   reserved   namespaces   (^_?([a-z0-9_.]+-)+[a-z0-9]+$);  and  the  Debian cron script namespace   (^[a-zA-Z0-9_-]+$).

Entonces, si tienes un script cron backup.sh, analyze-logs.pl en cron.daily/ directorio, lo mejor es eliminar los nombres de las extensiones.

En muchos entornos, cron ejecuta comandos usando sh, mientras que muchas personas asumen que usará bash.

Sugerencias para probar o corregir esto para un comando que falla:

  • Intente ejecutar el comando en sh para ver si funciona:

    sh -c "mycommand"
  • Envuelva el comando en una subcapa de bash para asegurarse de que se ejecute en bash:

    bash -c "mybashcommand"
  • Dígale a cron que ejecute todos los comandos en bash configurando el shell en la parte superior de su crontab:

    SHELL=/bin/bash
  • Si el comando es un script, asegúrese de que el script contenga un shebang:

    #!/bin/bash

Tuve algunos problemas con las zonas horarias. Cron se estaba ejecutando con la nueva zona horaria de instalación. La solución fue reiniciar cron:

sudo service cron restart

La ruta absoluta debe usarse para los scripts:

Por ejemplo, /bin/grep debe usarse en lugar de grep:

# m h  dom mon dow   command0 0 *  *  *  /bin/grep ERROR /home/adam/run.log &> /tmp/errors

En lugar de:

# m h  dom mon dow   command0 0 *  *  *  grep ERROR /home/adam/run.log &> /tmp/errors

Esto es especialmente complicado, porque el mismo comando funcionará cuando se ejecute desde el shell. La razón es que cron no tiene el mismo PATH variable de entorno como usuario.

Si el comando crontab tiene un % símbolo en él, cron intenta interpretarlo. Entonces, si estaba usando cualquier comando con un % en él (como una especificación de formato para el comando date) deberá escapar de él.

Eso y otras buenas trampas aquí:
http://www.pantz.org/software/cron/croninfo.html

Cron está llamando a un script que no es ejecutable.

Corriendo chmod +x /path/to/script, el script se vuelve ejecutable y esto debería resolver este problema.

También es posible que la contraseña del usuario haya caducado. Incluso la contraseña de root puede caducar. Usted puede tail -f /var/log/cron.log y verá que cron falla con la contraseña caducada. Puede configurar la contraseña para que nunca caduque haciendo esto: passwd -x -1 <username>

En algunos sistemas (Debian, Ubuntu), el registro para cron no está habilitado de forma predeterminada. En /etc / rsyslog.conf o /etc / rsyslog.d / 50-por defecto.conf fila:

# cron.*                          /var/log/cron.log

debería editarse (sudo nano /etc/rsyslog.conf) sin comentarios:

cron.*                          /var/log/cron.log

Después de eso, debe reiniciar rsyslog a través de

/etc/init.d/rsyslog restart

o

service rsyslog restart 

Fuente: Habilitar el registro de crontab en Debian Linux

En algunos sistemas (Ubuntu), el archivo de registro separado para cron no está habilitado de forma predeterminada, pero los registros relacionados con cron aparecen en el archivo syslog. Se puede usar

cat /var/log/syslog | grep cron -i

para ver los mensajes relacionados con cron.

Debe cerrar ‘crontab-e’ para que el cron surta efecto. Por ejemplo, usando vim edito el archivo y uso’: w ’ para escribirlo, pero el trabajo no se agrega a cron hasta que también lo dejo. Así que no veré el trabajo hasta después de`: q ’ también.

Creo que la mejor manera de depurar cron es verificar syslog y encontrar los problemas.

En mi caso, el correo electrónico iba a mi carpeta de correo no deseado, entonces… compruébalo antes de pasar horas depurando :smiley:

Cortes de electricidad

Por favor, compruebe este cron - Script doesn't run via crontab but works fine standalone - Ask Ubuntu