¿Por qué los scripts crontab no funcionan?

¿Por qué los scripts crontab no funcionan?

A menudo, crontablos scripts no se ejecutan según lo previsto o como se esperaba. Hay numerosas razones para ello:

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

Esta wiki comunitaria tiene como objetivo agregar las principales razones por las que crontablos scripts no se ejecutan como se esperaba. Escribe cada razón en una respuesta separada.

Incluya un motivo por respuesta (detalles sobre por qué no se ejecuta) y solucione ese motivo.

Escriba sólo problemas específicos de cron, por ejemplo, comandos que se ejecutan como se espera desde el shell pero que cron ejecuta erróneamente.

Respuesta1

Entorno diferente

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

* * * * * entorno > /tmp/env.output

Espere a /tmp/env.outputque se cree y luego elimine el trabajo nuevamente. Ahora compare el contenido de /tmp/env.outputcon la salida de envrun en su terminal habitual.

Un problema común aquí es que la PATHvariable de entorno es diferente. ¿Quizás su secuencia de comandos cron usa el comando somecommandque se encuentra en , al que /opt/someApp/binagregó ? cron ignora ese archivo, por lo que la ejecución desde su secuencia de comandos fallará cuando se ejecute con cron, pero funcionará cuando se ejecute en una terminal. Vale la pena señalar que las variables de se pasarán a los trabajos cron, pero no las variables que cron establece específicamente, como .PATH/etc/environmentPATHsomecommand/etc/environmentPATH

Para solucionar esto, simplemente configure su propia PATHvariable en la parte superior del script. P.ej

#!/bin/bash
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# rest of script follows

Algunos prefieren usar rutas absolutas para todos los comandos. Lo 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/binsu lugar. Tendría que revisar todo el script reemplazando /opt/someApp/bincon /opt/someAppv2.2/binen lugar de simplemente hacer una pequeña edición en la primera línea del script.

También puede configurar 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:/bin

15 1 * * * backupscript --incremental /home /root

Respuesta2

Mi principal problema: si olvida agregar una nueva línea al final del crontabarchivo. En otras palabras, el archivo crontab debería terminar con una línea vacía.

A continuación se muestra la sección relevante en las páginas de manual para este problema ( man crontabluego salte hasta el 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)

Respuesta3

El demonio cron no se está ejecutando. Realmente me equivoqué con esto hace algunos meses.

Tipo:

pgrep cron 

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

EDITAR: en lugar de invocar scripts de inicio a través de /etc/init.d, use la utilidad de servicio, por ejemplo

sudo service cron start

EDITAR: También puedes usar systemctl en Linux moderno, por ejemplo

sudo systemctl start cron

Respuesta4

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

Sugerencias para probar o solucionar este problema de un comando fallido:

  • Intente ejecutar el comando shpara ver si funciona:

    sh -c "mycommand"
    
  • Envuelva el comando en un subshell 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
    

información relacionada