¿Por qué los scripts crontab no funcionan?


525

A menudo, los crontabscripts no se ejecutan según lo programado o como se esperaba. Existen numerosas razones para eso:

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

Este wiki de la comunidad tiene como objetivo agregar las principales razones para que los crontabscripts no se ejecuten como se esperaba. Escribe cada razón en una respuesta separada.

Incluya una razón por respuesta (detalles sobre por qué no se ejecuta) y arregle (s) por esa razón.

Escriba solo problemas específicos de cron, por ejemplo, comandos que se ejecutan como se espera del shell pero que cron ejecuta erróneamente.


12
Debe cerrar crontab -epara que el cron surta efecto. Por ejemplo, usando vim edito el archivo y lo uso :wpara escribirlo, pero el trabajo no se agrega a cron hasta que también salga. Así que no veré el trabajo hasta después :qtambién.
DutGRIFF

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

En mi caso, el correo electrónico iba a mi carpeta de SPAM, así que ... verifique eso antes de pasar horas en la depuración: D
almaruf

Cortes de electricidad
Josef Klimuk

Respuestas:


501

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.output

Espere a /tmp/env.outputque se cree, luego elimine el trabajo nuevamente. Ahora compare el contenido de /tmp/env.outputcon la salida de envejecución en su terminal regular.

Un "problema" común aquí es que la PATHvariable de entorno es diferente. Tal vez la secuencia de comandos cron utiliza el comando somecommandque se encuentra en /opt/someApp/bin, que se ha añadido a PATHen /etc/environment? cron ignora PATHde ese archivo, por lo que la ejecución somecommandde 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/environmentse pasarán a los trabajos cron, pero no las variables que cron se establece específicamente, como PATH.

Para evitar eso, 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 a todos los comandos en su lugar. Recomiendo contra eso. Considere lo que sucede si desea ejecutar su script en un sistema diferente, y en ese sistema, el comando está en su /opt/someAppv2.2/binlugar. Tendría que pasar por todo el script reemplazando /opt/someApp/binen /opt/someAppv2.2/binlugar 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:/bin

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

55
Creo que me enamoré de esto, y la nueva línea al final ... doble golpe.
WernerCD

66
+1 porque env, me había olvidado por completo de ese comando y pensé que PATH estaba funcionando. En realidad fue ligeramente diferente en mi caso.
Izkata

8
@pbr Si dichos directorios se pueden escribir en otros, el sistema ya está comprometido.
geirha

66
@pbr Un administrador de sistemas podría eliminar involuntariamente el sistema de archivos raíz. No se puede evitar que los administradores de sistemas cometan errores tontos. Si instala una versión más nueva de un intérprete que no es compatible con versiones anteriores, de todos modos esperaría una rotura. La forma sensata de manejar eso es instalarlo como un comando diferente. Por ejemplo, tiene Python versión 2.xy instala Python 3, lo instala como python3, no como python. Y en cuanto a / opt / someApp / bin, ¿por qué no tendría permisos / propiedad sensata? cualquier administrador en su sano juicio garantizaría los permisos / propiedad en los archivos del sistema.
geirha

2
@pbr Parece que podríamos continuar para siempre, sí. Sin embargo, todavía no entiendo por qué es una mala idea usar PATH. Si tiene ganas de discutir esto más a fondo en un medio más adecuado para la discusión, me encontrará en #ubuntu y #bash, entre otros canales, en irc.freenode.net
geirha

336

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

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

9191
Este es un gran espectáculo, ¿por qué no se ha solucionado en tantos años de cron?
Capi Etheriel

2
Parece estar arreglado en Vixie cron: man crontaben Ubuntu 10.10 dice "cron requiere que cada entrada en un crontab termine en un carácter de nueva línea. Si la última entrada en un crontab falta la nueva línea, cron considerará que el crontab (al menos parcialmente) está roto y se niegan a instalarlo ". (Y la fecha final es el 19 de abril de 2010.)
Marius Gedminas

19
@barraponto Esto es realmente un error en los nuevos editores de texto. Se supone que el carácter de "nueva línea" es un carácter de terminación de línea , por lo que se supone que la línea final en un archivo de texto termina en un carácter de nueva línea que no se muestra en el editor. Vi y vim usan el personaje correctamente, y el cron se creó antes de que los nuevos editores comenzaran su comportamiento extraño ... Por lo tanto, al guardarlo e incluir una línea en blanco.
Izkata

66
Si edita crontab con crontab -eél, verificará la sintaxis del archivo antes de permitir un guardado, incluida una comprobación de nueva línea.
Tom Harrison Jr

2
@ Chan-HoSuh, según la página de manual "cron requiere que cada entrada en un crontab termine en un carácter de nueva línea. Si la última entrada en un crontab falta la nueva línea, cron considerará que el crontab (al menos parcialmente) está roto y se negará a instalarlo." Este comportamiento se invocará al editar y luego guardar el crontab usando la -eopción, y es independiente del editor.
Tom Harrison Jr

139

Cron daemon no se está ejecutando. Realmente lo arruiné hace algunos meses.

Tipo:

pgrep cron 

Si no ve ningún número, entonces cron no se está ejecutando. sudo /etc/init.d/cron startse puede usar para iniciar cron.

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

sudo service cron start

EDITAR: También podría usar systemctl en Linux moderno, por ejemplo

sudo systemctl start cron

47
Gracias por mostrarme pgrep. Seguí haciendo ps -ef | grep foo
ripper234

44
También puede usar el pidof croncual omitirá resultados para otras aplicaciones que también tienen la palabra 'cron', como crontab.
Pithikos

Extraño, todo esto no me da nada para mostrar que cron se está ejecutando, pero si corro sudo service cron startme salestart: Job is already running: cron
Colleen

1
service crond startif its centos / RHEL
Srihari Karanth

91

El guión en nombres de archivo cron.d/, cron.daily/, cron.hourly/, etc, no debe contener puntos ( .), de otro modo run-parts saltarán ellos.

Ver run-parts (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 tiene un script cron backup.sh, analyze-logs.plen el cron.daily/directorio, es mejor que elimine los nombres de extensión.


10
Es una característica, no un error: evita que cosas como myscript.backup o myscript.original o myscript.rpm-new se ejecuten justo al lado de myscript.
pbr

@pbr: tiene sentido. Al menos habría sido útil para la depuración si run-parts --test(u otra opción imaginaria como la --debugsalida de los archivos que omite, incluido el motivo.)
Rabarberski

99
Si esta es una característica, no es buena :( Muchas personas usan punto en el nombre del archivo (backup.sh es el más común). Si desea que un script deje de ejecutarse, el método más lógico será eliminarlo del directorio "cron.d"
MatuDuke

8
Esta es una característica tan mala que efectivamente es un error. Es una práctica común exigir un final particular (como ".list" o ".cron" o algo así) si la gente quiere asegurarse de que las cosas solo se ejecuten cuando se pretende. Elegir arbitrariamente el punto como un probable separador para ".bak" o ".temp" o lo que sea, es completamente impredecible, excepto en la forma en que predeciblemente confundirá a las personas. Las terminaciones legítimas como ".sh" y ".pl" se han utilizado ampliamente durante décadas. Sin embargo, muchas personas usan "_bak" o "_temp" o "-bak" en lugar de un punto. Esta es una elección de diseño horrible; es un error de diseño en el mejor de los casos.
Teekin

68

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

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

  • 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"
    
  • Dile a cron que ejecute todos los comandos en bash configurando el shell en la parte superior de tu crontab:

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

    #!/bin/bash
    

sugerencia de bash es muy útil, solucionado el problema con mi cron.
Maxim Galushka

Esto solo me causó 1 hora de violín / resolución de problemas. Aún más desconcertante si no está al tanto del problema es que el script se ejecutará manualmente bien si su shell típico es bash, pero no con cron. ¡Gracias!
Hendy

Hace mucho tiempo me encontré con algo relacionado: el comando sourceestá en bash pero no sh. En cron / sh, use un punto: en . envfilelugar de source envfile.
kungphu

@Clockwork sh "mycommand"le dice shque ejecute mycommand como un archivo de script. Quiso decir sh -c "mycommand"? En cualquier caso, esta respuesta parece ser sobre hacer que el comando se ejecute específicamente en bash, entonces, ¿por qué agregaste el comando shaquí?
Olorin

@Olorin Según tengo entendido, el objetivo del primer punto era intentar ejecutarlo con sh, para ver si el problema realmente surgió del hecho de que cron lo está ejecutando con sh en lugar de bash. Por otra parte, tengo poco conocimiento sobre el asunto, por lo que podría estar equivocado.
Mecanismo

40

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

sudo service cron restart

66
Sí, después de cambiar la zona horaria en un sistema, uno debe reiniciar todos los servicios que se preocupan por la hora o reiniciar. Prefiero el reinicio, para asegurarme de haberlo captado todo.
pbr

Oh, por el amor de Dios, maté horas en esto. Intenté reiniciar el servicio después de * * * * * touch /tmp/cronworksno hacer nada, pero hay RELOADcronlog.
Noviembre

36

La ruta absoluta debe usarse para los scripts:

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

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

En lugar de:

# m h  dom mon dow   command
0 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 cronno tiene la misma PATHvariable de entorno que el usuario.


3
vea la respuesta de geirha, puede (debe) definir la RUTA del cron
Capi Etheriel

99
Bzzt. NO es necesario que defina la RUTA: el uso de rutas absolutas es la mejor práctica aquí. "porque un ejecutable puede estar en otra parte en otra computadora" no triunfa "Quiero que ejecute exactamente este programa y no otro que alguien haya puesto en el camino frente a mi programa original"
pbr

1
sí, esto fue para mí, fuera del cron podía ejecutar el comando directamente, dentro del cron necesitaba /usr/bin/whateverruta completa
Anentropic

32

Si su comando crontab tiene un %símbolo, cron intenta interpretarlo. Por lo tanto, si estaba utilizando algún comando con un %(como una especificación de formato para el comando de fecha), deberá escapar.

Eso y otros buenos trucos aquí:
http://www.pantz.org/software/cron/croninfo.html


Esto es lo que ha estado haciendo que mi trabajo en Cron falle durante la última semana. Finalmente descubrí que mi Fecha no tenía un carácter de escape (barra invertida para cualquier otra persona que busque cuál es el personaje de escape). ¡Hurra!
Valien


25

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

Al ejecutar chmod +x /path/to/scripel script, se vuelve ejecutable y debe resolver este problema.


55
Eso no es exclusivo crony fácil de rastrear simplemente intentando ejecutar /path/to/scriptdesde la línea de comandos.
Adam Matan

44
Si está acostumbrado a ejecutar scripts con . scriptnameo sh scriptnameo bash scriptname, entonces esto se convierte en un cronproblema específico.
Eliah Kagan

24

También es posible que la contraseña del usuario haya expirado. Incluso la contraseña de root puede caducar. Puede tail -f /var/log/cron.logy verá que cron fallará 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 de cron no está habilitado de forma predeterminada. En /etc/rsyslog.conf o /etc/rsyslog.d/50-default.conf la línea:

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

debe ser editado ( sudo nano /etc/rsyslog.conf) sin comentarios para:

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: Habilite el registro 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. Uno puede usar

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

para ver mensajes relacionados con cron.


Tengo Debian (wheezy) pero no hay /etc/init.d/rsyslog, solo inetutils-syslogd y sysklogd. ¿Tengo que instalar algo o simplemente reiniciar uno de los dos?
hgoebl

18

Si su cronjob invoca aplicaciones GUI, debe decirles qué PANTALLA deben usar.

Ejemplo: lanzamiento de Firefox con cron.

Su script debe contener en export DISPLAY=:0alguna parte.


aplay necesitaba este por alguna razón. gracias
IljaBek

* * * * * export DISPLAY=:0 && <command>
LoMaPh

15

Los problemas de permisos son bastante comunes, me temo.

Tenga en cuenta que una solución común es ejecutar todo utilizando el crontab de root, que a veces es una idea realmente mala. Definir los permisos adecuados es definitivamente un problema que se pasa por alto en gran medida.


Tenga en cuenta que si tiene una línea crontab configurada para canalizar la salida a un archivo que aún no existe, y el directorio para el archivo es uno al que el usuario cron no tiene acceso, entonces la línea no se ejecutará.
Evan Donovan

14

Permiso inseguro de la tabla cron

Se rechaza una tabla cron si su permiso es inseguro

sudo service cron restart
grep -i cron /var/log/syslog|tail -2
2013-02-05T03:47:49.283841+01:00 ubuntu cron[49906]: (user) INSECURE MODE (mode 0600 expected) (crontabs/user)

El problema se resuelve con

# correct permission
sudo chmod 600 /var/spool/cron/crontabs/user
# signal crond to reload the file
sudo touch /var/spool/cron/crontabs

¡Primero lo descubrí yo mismo y luego encontré tu respuesta! Aún así muchas gracias! ¡En mi caso, había revertido / restaurado algunos crontabs en / var / spool / cron / crontabs a través de SVN que cambió sus permisos!
alfonx

12

El script es sensible a la ubicación. Esto está relacionado con el uso siempre de rutas absolutas en un script, pero no exactamente lo mismo. Es posible que su trabajo cron necesite cdun directorio específico antes de ejecutarse, por ejemplo, una tarea de rake en una aplicación Rails puede necesitar estar en la raíz de la aplicación para que Rake encuentre la tarea correcta, sin mencionar la configuración de base de datos adecuada, etc.

Entonces, una entrada crontab de

23 3 * * * /usr/bin/rake db:session_purge RAILS_ENV=production

sería mejor como

23 3 * * * cd / var / www / production / current && / usr / bin / rake db: session_purge RAILS_ENV = production

O, para mantener la entrada de crontab más simple y menos frágil:

23 3 * * * /home/<user>/scripts/session-purge.sh

con el siguiente código en /home/<user>/scripts/session-purge.sh:

cd / var / www / production / current
/ usr / bin / rake db: session_purge RAILS_ENV = producción

1
Si el script que se invoca desde cron está escrito en un lenguaje interpretado como PHP, es posible que deba configurar el directorio de trabajo en el script en sí. Por ejemplo, en PHP: chdir(dirname(__FILE__));
Evan Donovan

Acabo de quedar atrapado con este: el script solía estar en la raíz de mi directorio de inicio, pero luego lo moví (y actualicé el crontab) y no pude entender por qué no funcionaba. Resulta que el script estaba usando una ruta relativa, suponiendo que era relativo a la ubicación del script, pero de hecho era relativo a la raíz de mi directorio de inicio porque ese era el directorio de trabajo que estaba usando cron, razón por la cual el script trabajó cuando estaba en la raíz de mi directorio personal (porque se esperaba directorio de trabajo del guión y que está trabajando muy real que ocurrió en coincidencia).
Micheal Johnson

11

Las especificaciones de Crontab que funcionaban en el pasado pueden romperse cuando se mueven de un archivo crontab a otro. A veces, la razón es que ha movido la especificación de un archivo crontab del sistema a un archivo crontab de usuario o viceversa.

El formato de especificación de trabajo cron difiere entre los archivos crontab de los usuarios (/ var / spool / cron / username o / var / spool / cron / crontabs / username) y los crontabs del sistema ( /etc/crontaby los archivos en /etc/cron.d).

Los crontabs del sistema tienen un campo adicional 'usuario' justo antes del comando para ejecutar.

Esto provocará errores que indiquen cosas como george; command not foundcuando mueves un comando /etc/crontabo un archivo /etc/cron.dal archivo crontab de un usuario.

Por el contrario, cron entregará errores similares /usr/bin/restartxyz is not a valid usernameo similares cuando ocurra lo contrario.


10

El script cron invoca un comando con la opción --verbose

Tuve un error de secuencia de comandos cron en mí porque estaba en piloto automático mientras escribía la secuencia de comandos e incluí la opción --verbose:

#!/bin/bash
some commands
tar cvfz /my/archive/file.tar.gz /my/shared/directory
come more commands

El script se ejecutó bien cuando se ejecutó desde shell, pero falló cuando se ejecutó desde crontab porque la salida detallada va a stdout cuando se ejecuta desde shell, pero en ninguna parte cuando se ejecuta desde crontab. Solución fácil para eliminar la 'v':

#!/bin/bash
some commands
tar cfz /my/archive/file.tar.gz /my/shared/directory
some more commands

55
¿Por qué esto está causando un fracaso? Problemas de búfer?
Adam Matan

Cualquier salida o error desencadenado a través de trabajos cron se envía a su buzón de correo, por lo que nunca debemos olvidar preocuparnos por estos errores / salida. Podemos redirigirlos a cualquier archivo o / dev / null
Nischay

10

La razón más frecuente por la que he visto que cron falla en un horario incorrectamente establecido. Se necesita práctica para especificar un trabajo programado para las 11:15 pm como en 15 23 * * *lugar de * * 11 15 *o 11 15 * * *. El día de la semana para los trabajos después de la medianoche también se confunde MF es 2-6después de la medianoche, no 1-5. Las fechas específicas suelen ser un problema, ya que rara vez las usamos * * 3 1 *no es el 3 de marzo. Si no está seguro, consulte sus cronogramas cron en línea en https://crontab.guru/ .

Si su trabajo con diferentes plataformas utilizando opciones no compatibles, como las 2/3especificaciones de tiempo, también puede causar fallas. Esta es una opción muy útil pero no está disponible universalmente. También me he encontrado con problemas con listas como 1-5o 1,3,5.

El uso de rutas no calificadas también ha causado problemas. La ruta predeterminada suele ser /bin:/usr/binasí que solo se ejecutarán los comandos estándar. Estos directorios generalmente no tienen el comando deseado. Esto también afecta a los scripts que utilizan comandos no estándar. También pueden faltar otras variables de entorno.

Clobbering un crontab existente me ha causado problemas por completo. Ahora cargo desde una copia de archivo. Esto se puede recuperar del crontab existente usando crontab -lsi se golpea. Mantengo la copia de crontab en ~ / bin. Se comenta en todo momento y termina con la línea # EOF. Esto se recarga diariamente desde una entrada crontab como:

#! / usr / bin / crontab
# Recargar este crontab
# #
54 12 * * * $ {HOME} / bin / crontab

El comando de recarga anterior se basa en un crontab ejecutable con una ruta de acceso que ejecuta crontab. Algunos sistemas requieren la ejecución de crontab en el comando y la especificación del archivo. Si el directorio es compartido en red, a menudo lo uso crontab.$(hostname)como el nombre del archivo. Esto eventualmente corregirá los casos en los que se carga el crontab incorrecto en el servidor incorrecto.

El uso del archivo proporciona una copia de seguridad de lo que debería ser el crontab, y permite que las ediciones temporales (la única vez que uso crontab -e) se restituyan automáticamente. Hay encabezados disponibles que ayudan a obtener los parámetros de programación correctos. Los he agregado cuando los usuarios inexpertos estarían editando un crontab.

Raramente, me he encontrado con comandos que requieren la entrada del usuario. Estos fallan en crontab, aunque algunos funcionarán con la redirección de entrada.


3
Esto cubre tres problemas separados. ¿Se pueden dividir en respuestas separadas?
Eliah Kagan

99
¿Puedes explicar cómo se 30 23 * * * traduce a las 11:15 PM?
JYelton

@JYelton Eso obviamente estaba mal, debería estarlo 15 23 * * *. Corregido ahora.
Melebius

7

Si está accediendo a una cuenta a través de claves SSH, es posible iniciar sesión en la cuenta, pero no se da cuenta de que la contraseña de la cuenta está bloqueada (por ejemplo, debido a intentos de contraseña vencidos o no válidos)

Si el sistema usa PAM y la cuenta está bloqueada, esto puede detener la ejecución de su cronjob. (He probado esto en Solaris, pero no en Ubuntu)

Puede encontrar mensajes como este en / var / adm / messages:

24 de octubre 07:51:00 mybox cron [29024]: [ID 731128 auth.notice] pam_unix_account: cron intenta validar la cuenta bloqueada myuser del host local
24 de octubre 07:52:00 mybox cron [29063]: [ID 731128 auth.notice] pam_unix_account: cron intenta validar la cuenta bloqueada myuser del host local
24 de octubre 07:53:00 mybox cron [29098]: [ID 731128 auth.notice] pam_unix_account: cron intenta validar la cuenta bloqueada myuser desde el host local
24 de octubre 07:54:00 mybox cron [29527]: [ID 731128 auth.notice] pam_unix_account: cron intenta validar la cuenta bloqueada myuser desde el host local

Todo lo que debe hacer es ejecutar:

# passwd -u <USERNAME>

como root para desbloquear la cuenta, y el crontab debería funcionar nuevamente.


7

Si tiene un comando como este:

* * * * * /path/to/script >> /tmp/output

y no funciona y no puede ver ningún resultado, no necesariamente significa que cron no está funcionando. El script podría romperse y la salida iría a stderr que no se pasa a / tmp / output. Comprueba que este no es el caso, capturando también esta salida:

* * * * * /path/to/script >> /tmp/output 2>&1

para ver si esto te ayuda a resolver tu problema.


3

=== Alerta Docker ===

Si estás usando docker,

Creo que es correcto agregar que no pude hacer que cron se ejecute en segundo plano.

Para ejecutar un trabajo cron dentro del contenedor, utilicé supervisor y ejecuté cron -f, junto con el otro proceso.

Editar: Otro problema: tampoco logré que funcionara al ejecutar el contenedor con la red HOST. Vea este problema aquí también: https://github.com/phusion/baseimage-docker/issues/144



3

Estaba escribiendo un script de instalación de shell que crea otro script para purgar los datos de transacciones anteriores de una base de datos. Como parte de la tarea, tenía que configurar el crontrabajo diario para ejecutarse en un momento arbitrario, cuando la carga de la base de datos era baja.

Creé un archivo mycronjobcon cron cronograma, nombre de usuario y el comando y lo copié en el /etc/cron.ddirectorio. Mis dos trampas:

  1. mycronjob el archivo tenía que ser propiedad de root para ejecutarse
  2. Tuve que configurar los permisos del archivo a 644 - 664 no se ejecutaría.

Un problema de permiso aparecerá /var/log/syslogcomo algo similar a:

Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/crontab)
Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/cron.d/user)

La primera línea se refiere al /etc/crontabarchivo y la posterior a un archivo que coloqué debajo /etc/cront.d.


2

Línea escrita de una manera que crontab no entiende. Tiene que estar escrito correctamente. Aquí está CrontabHowTo .


1
¿Cómo se puede depurar esto?
Adam Matan

Revisar el registro de errores de cron es la forma más común. IIRC 'crontab -e' hace un análisis sintáctico después de que también haya editado el archivo, pero puede que no sea universal.
pbr

2

Cron daemon podría estar ejecutándose, pero en realidad no funciona. Intenta reiniciar cron:

sudo /etc/init.d/cron restart

3
NUNCA he visto este caso en producción. No significa que no haya sucedido, solo que no lo he visto en los 30 años que llevo usando UNIX y Linux. Cron es increíblemente robusto.
pbr

1
No estoy seguro, pero creo que esto realmente me sucedió a mí. Intenté pidofcron y no obtuve nada. Intenté usar la serviceutilidad y decía que cron ya se estaba ejecutando. Simplemente ejecuté este comando y ejecuté pidofnuevamente y obtuve un resultado.
Colleen

2

Escribir en cron a través de "crontab -e" con el argumento de nombre de usuario en una línea. He visto ejemplos de usuarios (o administradores de sistemas) que escriben sus scripts de shell y no entienden por qué no se automatizan. El argumento "usuario" existe en / etc / crontab, pero no en los archivos definidos por el usuario. entonces, por ejemplo, su archivo personal sería algo como:

# m h dom mon dow command

* * */2  *   *  /some/shell/script

mientras que / etc / crontab sería:

# m h dom mon dow user   command

* * */2  *   *  jdoe   /some/shell/script

Entonces, ¿por qué harías lo último? Bueno, dependiendo de cómo desee establecer sus permisos, esto puede ser muy complicado. He escrito guiones para automatizar tareas para usuarios que no entienden las complejidades o que no quieren molestarse con el trabajo pesado. Al establecer permisos para --x------, puedo hacer que el script sea ejecutable sin que puedan leerlo (y quizás cambiarlo accidentalmente). Sin embargo, es posible que desee ejecutar este comando con varios otros desde un archivo (lo que hace que sea más fácil de mantener), pero asegúrese de que la salida del archivo esté asignada al propietario correcto. Al hacerlo (al menos en Ubuntu 10.10) se interrumpe tanto la incapacidad para leer el archivo como para ejecutarlo, más el problema antes mencionado de poner períodos en / etc / crontab (que, curiosamente, no causa ningún error al pasar crontab -e) .

A modo de ejemplo, he visto instancias sudo crontab -eutilizadas para ejecutar un script con permisos de root, con un correspondiente chown username file_outputen el script de shell. Descuidado, pero funciona. En mi humilde opinión, la opción más elegante es ponerlo /etc/crontabcon el nombre de usuario declarado y los permisos adecuados, por lo que file_outputva al lugar correcto y al propietario.


"Hacerlo (al menos en Ubuntu 10.10) interrumpe tanto la incapacidad para leer el archivo como para ejecutar ....." Debo aclarar: / etc / crontab (por defecto) requiere permisos de lectura Y ejecución, mientras que PODRÍAS ejecute "sudo crontab -e" para crear un cronjob que anule tanto la necesidad del permiso "w" como el problema con extensiones como ".sh". No he tenido tiempo de separar el código cron y comprobar por qué funciona, solo un detalle que he notado.
Mange

2

A partir de lo que Aaron Peart mencionó sobre el modo detallado, a veces las secuencias de comandos que no están en modo detallado se inicializarán pero no finalizarán si el comportamiento predeterminado de un comando incluido es generar una línea o más en la pantalla una vez que se inicia el proceso. Por ejemplo, escribí un script de respaldo para nuestra intranet que usaba curl, una utilidad que descarga o carga archivos a servidores remotos, y es bastante útil si solo puede acceder a dichos archivos remotos a través de HTTP. El uso de 'curl http://something.com/somefile.xls ' estaba causando que un script que escribí se bloqueara y nunca completara porque escupe una nueva línea seguida de una línea de progreso. Tuve que usar el indicador de silencio (-s) para decirle que no mostrara ninguna información y escribir mi propio código para controlar si el archivo no se pudo descargar.


1
Para los programas que no tienen un modo silencioso, puede redirigir su salida a /dev/null. Por ejemplo: some-command > /dev/nullEsto redirigirá solo la salida estándar, y no la salida de error (que generalmente es lo que desea, ya que desea que se le informe de los errores). Para redirigir la salida de error también, use some-command &> /dev/null.
Eliah Kagan

Sí, ese fue mi primer pensamiento al escribir el guión mencionado anteriormente. Olvidé por qué no usé eso, posiblemente algún comportamiento no estándar que eludió dicha solución. Sé que el modo detallado / interactivo es el predeterminado en algunos comandos (¡lo estoy mirando a USTED, scp!), Lo que significa que necesita manipular dicha salida para que las secuencias de comandos de shell funcionen sin problemas.
Mange

2

Aunque puede definir variables de entorno en su crontable, no está en un script de shell. Entonces las construcciones como las siguientes no funcionarán:

SOME_DIR=/var/log
MY_LOG_FILE=${SOME_LOG}/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=${BIN_DIR}/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}

Esto se debe a que las variables no se interpretan en el crontable: todos los valores se toman literalmente. Y esto es lo mismo si omite los corchetes. Por lo tanto, sus comandos no se ejecutarán y sus archivos de registro no se escribirán ...

En su lugar, debe definir todas las variables de entorno directamente:

SOME_DIR=/var/log
MY_LOG_FILE=/var/log/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=/usr/local/bin/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}

2

Cuando se ejecuta una tarea dentro de cron, stdin se cierra. Los programas que actúan de manera diferente en función de si stdin está disponible o no se comportarán de manera diferente entre la sesión de shell y en cron.

Un ejemplo es el programa goaccesspara analizar archivos de registro del servidor web. Esto NO funciona en cron:

goaccess -a -f /var/log/nginx/access.log > output.html

y goaccessmuestra la página de ayuda en lugar de crear el informe. En la cáscara esto se puede reproducir con

goaccess -a -f /var/log/nginx/access.log > output.html < /dev/null

La solución goaccesses hacer que lea el registro desde stdin en lugar de leerlo desde el archivo, por lo que la solución es cambiar la entrada crontab a

cat /var/log/nginx/access.log | goaccess -a > output.html

2

En mi caso, cron y crontab tenían diferentes propietarios.

NO funcionaba tuve esto:

User@Uva ~ $ ps -ef | grep cron | grep -v grep
User    2940    7284 pty1     19:58:41 /usr/bin/crontab
SYSTEM   11292     636 ?        22:14:15 /usr/sbin/cro 

Básicamente tuve que ejecutar cron-config y responder las preguntas correctamente. Hay un punto en el que se me solicitó ingresar mi contraseña de usuario de Win7 para mi cuenta de 'Usuario'. Por lo que leí, parece que este es un posible problema de seguridad, pero soy el único administrador en una sola red doméstica, así que decidí que estaba bien.

Aquí está la secuencia de comandos que me puso en marcha:

User@Uva ~ $ cron-config
The cron daemon can run as a service or as a job. The latter is not recommended.
Cron is already installed as a service under account LocalSystem.
Do you want to remove or reinstall it? (yes/no) yes
OK. The cron service was removed.

Do you want to install the cron daemon as a service? (yes/no) yes
Enter the value of CYGWIN for the daemon: [ ] ntsec

You must decide under what account the cron daemon will run.
If you are the only user on this machine, the daemon can run as yourself.
   This gives access to all network drives but only allows you as user.
To run multiple users, cron must change user context without knowing
  the passwords. There are three methods to do that, as explained in
  http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1
If all the cron users have executed "passwd -R" (see man passwd),
  which provides access to network drives, or if you are using the
  cyglsa package, then cron should run under the local system account.
Otherwise you need to have or to create a privileged account.
  This script will help you do so.
Do you want the cron daemon to run as yourself? (yes/no) no

Were the passwords of all cron users saved with "passwd -R", or
are you using the cyglsa package ? (yes/no) no

Finding or creating a privileged user.
The following accounts were found: 'cyg_server' .
This script plans to use account cyg_server.
Do you want to use another privileged account name? (yes/no) yes
Enter the other name: User

Reenter: User


Account User already exists. Checking its privileges.
INFO: User is a valid privileged account.
INFO: The cygwin user name for account User is User.

Please enter the password for user 'User':
Reenter:
Running cron_diagnose ...
... no problem found.

Do you want to start the cron daemon as a service now? (yes/no) yes
OK. The cron daemon is now running.

In case of problem, examine the log file for cron,
/var/log/cron.log, and the Windows event log (using /usr/bin/cronevents)
for information about the problem cron is having.

Examine also any cron.log file in the HOME directory
(or the file specified in MAILTO) and cron related files in /tmp.

If you cannot fix the problem, then report it to cygwin@cygwin.com.
Please run the script /usr/bin/cronbug and ATTACH its output
(the file cronbug.txt) to your e-mail.

WARNING: PATH may be set differently under cron than in interactive shells.
         Names such as "find" and "date" may refer to Windows programs.


User@Uva ~ $ ps -ef | grep cron | grep -v grep
    User    2944   11780 ?        03:31:10 /usr/sbin/cron
    User    2940    7284 pty1     19:58:41 /usr/bin/crontab

User@Uva ~ $

1
Aunque bien documentado, esto parece un punto específico de Cygwin; ¿realmente pertenece a askubuntu?
sxc731

2

En mis servidores RHEL7, los trabajos cron de root se ejecutarían, pero los trabajos de usuario no. Descubrí que sin un directorio de inicio, los trabajos no se ejecutarán (pero verá buenos errores en / var / log / cron). Cuando creé el directorio de inicio, el problema se resolvió.


2

Si editó su archivo crontab usando un editor de Windows (a través de samba o algo así) y reemplazó las nuevas líneas con \ n \ r o simplemente \ r, cron no se ejecutará.

Además, si está usando /etc/cron.d/* y uno de esos archivos tiene \ r, cron se moverá a través de los archivos y se detendrá cuando llegue a un archivo defectuoso. ¿No estás seguro si ese es el problema?

Utilizar:

od -c /etc/cron.d/* | grep \r
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.