Configurar un cron job: planificación, permisos y errores frecuentes
El job funciona en la shell, pero no en cron. Esta guía explica los cinco campos de tiempo, la diferencia entre la crontab de usuario y /etc/cron.d, la trampa del PATH y cómo demostrar que una ejecución terminó de verdad.
Un cron job se configura en cinco minutos y después suele costar horas. El comando funciona sin problemas en la shell, desde cron no pasa nada, y en el log aparece como mucho que cron ha iniciado algo. Este artículo trata justo los puntos donde terminan las guías habituales: los mensajes de error reales, las diferencias entre distribuciones y la pregunta de cómo saber si un job llegó de verdad hasta el final y no solo se inició.
Todos los datos se refieren a Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS y Ubuntu 22.04 LTS. Estas cuatro usan el mismo cron (la variante Debian de Vixie Cron), no cronie como Red Hat y Fedora. Esa diferencia resulta decisiva más adelante, al llegar a la zona horaria.
¿Se está ejecutando siquiera el servicio cron?
En instalaciones completas cron está presente. En imágenes cloud mínimas, imágenes base de contenedores e instalaciones netinst reducidas falta el paquete con frecuencia. Esa es la primera pregunta que deberías aclarar antes de depurar cualquier otra cosa.
command -v crontab
systemctl status cron
A propósito command -v crontab y no command -v cron: el servicio en sí está en /usr/sbin, y en Debian ese directorio solo aparece en la ruta de búsqueda de root. Como usuario normal simplemente no obtienes ninguna salida, aunque cron esté instalado. En Ubuntu 24.04 la consulta también funciona con un usuario sin privilegios. crontab, en cambio, está en /usr/bin en todas partes y por tanto resulta visible para cualquiera, y systemctl status cron responde de todos modos a la pregunta más importante, es decir, si el servicio también se está ejecutando.
Si el servicio no está, lo instalas:
apt-get update
apt-get install -y cron
systemctl enable --now cron
En Debian y Ubuntu el servicio se llama cron, no crond. Quien viene acostumbrado a Red Hat recibe aquí un Unit crond.service could not be found. y busca en el sitio equivocado.
En funcionamiento normal no hace falta reiniciar nada: el cron de Debian vigila los directorios de crontab mediante inotify y lee los cambios por sí mismo. Después de editar una crontab no tienes que reiniciar nada. Las excepciones son el cambio de la zona horaria del sistema y las modificaciones en /etc/default/cron.
Los cinco campos, y la trampa del quinto
Cada línea empieza con cinco campos de tiempo, después viene el comando.
| Campo | Rango | Nota |
| Minuto | 0 a 59 | |
| Hora | 0 a 23 | formato de 24 horas, sin zona horaria |
| Día del mes | 1 a 31 | |
| Mes | 1 a 12 | también de jan a dec |
| Día de la semana | 0 a 7 | 0 y 7 son ambos domingo, también de sun a sat |
30 4 * * * /usr/local/bin/backup.sh # a diario a las 04:30
*/10 * * * * /usr/local/bin/check.sh # cada 10 minutos
0 2 * * 0 /usr/local/bin/weekly.sh # los domingos a las 02:00
15 3 1 * * /usr/local/bin/monthly.sh # el día 1 a las 03:15
0 9-17 * * 1-5 /usr/local/bin/business.sh # cada hora en días laborables, de 9 a 17
Dos detalles se malinterpretan casi siempre.
El día del mes y el día de la semana son un O, no un Y. En cuanto ambos campos están restringidos, es decir, ninguno contiene un asterisco, el job se ejecuta cuando coincide uno de los dos. 0 3 13 * 5 no significa "viernes 13", sino "todos los días 13 y además todos los viernes". Si de verdad quieres el viernes 13, lo compruebas dentro del propio script.
Los intervalos no reparten de forma uniforme. */7 * * * * se ejecuta en los minutos 0, 7, 14, 21, 28, 35, 42, 49 y 56, y después el contador salta a la hora siguiente. Entre el 56 y el 0 pasan por tanto solo cuatro minutos. Esto vale para cualquier intervalo que no divida de forma exacta 60 o 24. Para "cada 90 minutos" no existe una notación limpia en cron, aquí un timer de systemd es la mejor opción.
Usar crontab -e correctamente
La crontab de usuario no la editas nunca directamente en /var/spool/cron/crontabs/, siempre a través de la herramienta:
crontab -e
En la primera llamada el programa responde con no crontab for root - using an empty one. En sistemas recién instalados aparece a continuación una selección de editor. Si no hay ningún editor, por ejemplo en una imagen reducida, la llamada aborta con un mensaje como /usr/bin/sensible-editor: 25: editor: not found. Solución: instalar un editor o indicar de forma explícita el editor deseado.
apt-get install -y nano
EDITOR=nano crontab -e
La gran ventaja de crontab -e frente a escribir el archivo directamente es la comprobación al guardar. Si una línea está rota, ves:
"/tmp/crontab.7hK2mn/crontab":3: bad minute
errors in crontab file, can't install.
Do you want to retry the same edit? (y/n)
El número de línea es correcto, el campo que nombra el mensaje no siempre: bad minute aparece también cuando sencillamente falta un campo, porque entonces el parser lee todo desplazado hacia la izquierda. Si todo va bien, el proceso termina con crontab: installing new crontab. Solo esa línea significa que el cambio se ha aplicado.
Otros comandos que deberías conocer:
crontab -l # mostrar
crontab -l > /root/crontab.bak # guardar copia
crontab -u www-data -l # leer la crontab de otro usuario (como root)
crontab -i -r # borrar, con confirmación (solo en el terminal)
Una advertencia sobre la copia de seguridad: crontab -l > /root/crontab.bak informa no crontab for root y devuelve el código de salida 1 mientras no exista todavía ninguna crontab para ese usuario. El archivo de destino se crea igualmente, entonces con 0 bytes. Siguiendo el orden de este artículo no llama la atención, pero en un script que comprueba el código de retorno o que sobrescribe un backup más antiguo, desde luego que sí.
crontab -r sin -i borra la crontab completa de inmediato y sin preguntar. Como r y e no están lejos en el teclado, este es un caso real de pérdida de datos. Acostúmbrate por eso a usar crontab -i -r en el terminal y haz antes una copia con crontab -l.
La palabra clave aquí es terminal. crontab -i -r es un comando puramente interactivo. Si la entrada estándar no cuelga de un terminal, es decir, dentro de un script, dentro de un cron job o en una línea suelta como ssh host "crontab -i -r", la pregunta de confirmación gira sin fin: crontab: really delete root's crontab? (y/n) Please enter Y or N: Please enter Y or N: ... se repite sin límite y escribe cientos de kilobytes de salida en segundos; la llamada solo termina si la interrumpes desde fuera. Para todo lo automatizado usas por eso la variante no interactiva y haces antes una copia:
crontab -l > /root/crontab.bak # copia antes de borrar
crontab -r # borrar, sin confirmación
printf "y\n" | crontab -i -r # mantener la pregunta, dar la respuesta
Si existen /etc/cron.allow o /etc/cron.deny, ellos deciden quién puede crear crontabs. Los usuarios afectados reciben: You (username) are not allowed to use this program (crontab). Si /etc/cron.allow está presente, se aplica en exclusiva y todo usuario que no aparezca en la lista queda bloqueado.
Crontab de usuario, /etc/crontab y /etc/cron.d
Hay cuatro sitios donde pueden estar los planes de ejecución, y tienen formatos distintos. Justo aquí nacen los errores más difíciles de encontrar.
Crontab de usuario: cinco campos
Se mantiene con crontab -e, se ejecuta bajo el usuario al que pertenece y no tiene campo de usuario. Si aun así escribes uno, cron intenta ejecutar el nombre de usuario como comando y en el correo o en el log encuentras:
/bin/sh: 1: root: not found
/etc/cron.d: seis campos
Los archivos en /etc/cron.d/ son crontabs del sistema y llevan un campo de usuario entre los campos de tiempo y el comando. Este es el lugar adecuado para jobs que pertenecen a una aplicación o a una gestión de configuración, porque cada archivo se puede reemplazar por separado.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=""
0 3 * * * root /usr/local/bin/backup.sh >> /var/log/kh-backup.log 2>&1
Si olvidas el campo de usuario, cron interpreta la primera palabra del comando como nombre de usuario y la línea falla en silencio, porque ese usuario no existe.
Tres reglas para /etc/cron.d/ se incumplen con regularidad:
- El nombre del archivo no puede contener un punto. Solo se permiten letras, cifras, guiones bajos y guiones.
backup.cronokh-backup.shse ignoran sin comentario alguno. La razón es la gestión de paquetes: así, restos como.dpkg-disto.dpkg-oldnunca se ejecutan. Llama al archivo sencillamentekh-backup. - Los permisos y el propietario tienen que ser correctos. Se esperan
root:rooty modo 0644. De lo contrario, en el log aparecen mensajes como(*system*) WRONG FILE OWNER,(*system*) BAD FILE MODEo un aviso sobre un modo inseguro, con permiso de escritura para el grupo o para otros. El job entonces no se ejecuta. - El archivo tiene que terminar con un salto de línea. cron exige que cada entrada acabe con un newline. Si la última línea termina sin salto, se pasa por alto, y sin comentario alguno: en una prueba de control con un archivo por lo demás idéntico pero sin salto final, el job no se ejecutó ni una sola vez, sin mensaje de error y sin línea de log. Quien genera el archivo con
echo -n, con unprintfsin\nfinal o desde una plantilla sin línea vacía al final, pierde justo ese último job.
chown root:root /etc/cron.d/kh-backup
chmod 0644 /etc/cron.d/kh-backup
/etc/crontab y los directorios cron.*
/etc/crontab tiene igualmente seis campos y pertenece a la distribución. Cámbialo solo si sabes por qué. A través de run-parts llama a los directorios /etc/cron.hourly, cron.daily, cron.weekly y cron.monthly. Los scripts que hay ahí necesitan el bit de ejecución y tampoco pueden llevar un punto en el nombre. Un backup.sh en /etc/cron.daily/ no se ejecuta nunca, un backup sí. Puedes probarlo sin ejecutar nada:
run-parts --test /etc/cron.daily
Solo se muestran los scripts que run-parts iniciaría realmente. Si el tuyo falta en la lista, la causa está en el nombre o en el bit de ejecución.
Por qué el PATH dentro de cron es otro
Esta es con diferencia la causa más frecuente de "funciona en la shell, pero no en cron". cron no inicia una shell de login. No se leen ni ~/.bashrc ni ~/.profile ni /etc/profile. Para las crontabs de usuario, el cron de Debian establece una ruta de búsqueda mínima:
PATH=/usr/bin:/bin
Con eso faltan /usr/local/bin y /usr/sbin. En Debian 12, Debian 13, Ubuntu 22.04 y Ubuntu 24.04, /usr/bin y /usr/sbin siguen siendo directorios separados, ya que el usr merge solo afecta a /bin y /sbin. Todo lo que hayas puesto tú mismo en /usr/local/bin, todo lo que venga de pip install, todo lo de un Node gestionado con nvm y herramientas del sistema como ufw o iptables sencillamente no existen para cron. El mensaje de error dice entonces:
/bin/sh: 1: backup.sh: not found
La segunda parte de la trampa: cron establece SHELL=/bin/sh. En Debian y Ubuntu, /bin/sh es un enlace a dash, no a bash. Cualquier construcción propia de bash en la cabecera del script o directamente en la línea de la crontab falla:
/bin/sh: 1: [[: not found
/bin/sh: 1: source: not found
/bin/sh: 1: Syntax error: "(" unexpected
Tres contramedidas, en este orden:
- Usar rutas absolutas.
/usr/local/bin/backup.shen lugar debackup.sh,/usr/bin/phpen lugar dephp. Es la variante más robusta, porque funciona con independencia de cualquier variable de entorno. Pero lee la ruta del sistema en vez de escribirla de memoria:command -v datedevuelve en Debian 13, Debian 12, Ubuntu 24.04 y Ubuntu 22.04/usr/bin/date, mientras que en sistemas más antiguos como Debian 11 devuelve/bin/date. Una línea con una ruta equivocada la acepta crontab sin comentarios y sin avisos; solo falla en tiempo de ejecución y además en silencio. Para comprobarlo, ejecuta una vezcrontab -ly una vezenv -i /bin/sh -c "/usr/bin/date", que informa de una ruta equivocada al instante connot found. - Definir PATH y SHELL al principio de la crontab. Las asignaciones valen para todas las líneas siguientes. Importante: cron no expande variables ahí,
PATH=$PATH:/opt/binno funciona, escribe la ruta completa. - Usar un script wrapper. La línea de la crontab solo llama al script, y el script establece su propio entorno.
#!/bin/bash
set -euo pipefail
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
cd /srv/app
exec ./do-the-work.sh
Si quieres saber qué le entrega cron realmente a tu job, haz que te lo muestre. Añade durante un minuto:
* * * * * /usr/bin/env > /tmp/cron-env.txt 2>&1
Solo esta vía muestra el entorno que cron establece de verdad. Una shell reconstruida con env -i se queda simplemente cerca, porque trae su propia ruta por defecto. Después comparas /tmp/cron-env.txt con tu entorno interactivo. Lo llamativo no suelen ser solo PATH y SHELL, sino también las variables de locale que faltan. Sin LANG todo corre en la locale C, lo que cambia el orden de clasificación, los formatos de fecha y la salida de caracteres acentuados. Los scripts que dependen de LANG=de_DE.UTF-8 se comportan de otra manera dentro de cron. También falta el ssh-agent, por lo que los jobs con acceso SSH necesitan una clave sin passphrase y un -i explícito.
La última pequeña maldad de esta categoría: el signo de porcentaje. En una línea de crontab, un % sin escapar se convierte en un salto de línea, y todo lo que venga después llega al comando como entrada estándar. Los formatos de fecha hay que escaparlos, por tanto.
0 2 * * * /usr/bin/tar -czf /backup/web-$(date +\%F).tar.gz /var/www
Redirigir la salida, correos y "No MTA installed"
Por defecto, cron envía por correo al propietario de la crontab todo lo que un job escribe en stdout o stderr. En un servidor sin sistema de correo eso acaba en el log:
(CRON) info (No MTA installed, discarding output)
No es un fallo del job. Solo significa que hubo salida y nadie pudo recogerla. Un job silencioso no genera esta línea. Por eso es incluso una señal útil: si aparece de repente, tu job ha empezado a producir salida, normalmente un mensaje de error.
Para la redirección hay tres patrones razonables:
# todo a un archivo de log, incluidos los errores
0 3 * * * /usr/local/bin/backup.sh >> /var/log/kh-backup.log 2>&1
# descartar la salida normal, los errores siguen por correo
0 3 * * * /usr/local/bin/backup.sh > /dev/null
# todo al journal, bien etiquetado
0 3 * * * /usr/local/bin/backup.sh 2>&1 | /usr/bin/logger -t kh-backup
La variante > /dev/null 2>&1 es popular y peligrosa: tira también todos los mensajes de error. Un job que lleva cuatro meses fallando tiene entonces exactamente el mismo aspecto que uno que funciona. Si quieres prescindir de los correos, pon mejor MAILTO="" al principio de la crontab y escribe la salida en un archivo. Si quieres correos a una dirección concreta, defines MAILTO=alerts@example.org, pero para eso necesitas un sistema de correo instalado.
Tus propios archivos de log en /var/log/ crecen sin límite. Crea para ellos una pequeña regla en /etc/logrotate.d/, si no, el cron job con más éxito acabará llenándote el disco.
Cómo saber que realmente se ejecutó
Aquí se separa la guía rápida de la comprobación fiable. cron registra el inicio de un job. No registra ni el final ni el código de salida. Una línea CMD en el log demuestra por tanto solo que cron ha iniciado la shell, no que tu script haya tenido éxito.
Los logs se leen de forma distinta según el sistema:
journalctl -u cron --since "30 min ago"
journalctl -t CRON --since today
En Debian 12 y Debian 13 este es el único camino, porque desde bookworm rsyslog ya no se instala por defecto. Allí, por lo general, ya no existe un archivo /var/log/syslog. Quien lo busca y no lo encuentra da el job por no iniciado sin razón.
En Ubuntu 22.04 y 24.04 rsyslog suele estar presente, así que allí funciona además:
grep CRON /var/log/syslog
Un /var/log/cron.log propio no viene de fábrica en ninguna de las cuatro versiones. La regla correspondiente en /etc/rsyslog.d/50-default.conf está comentada. No busques ese archivo, solo existe si alguien lo ha activado.
Una prueba sólida viene por eso del propio job. Haz que el script escriba al final una marca de tiempo y el código de salida:
#!/bin/bash
set -euo pipefail
trap 'echo "$(date -Is) kh-backup finalizado, exit $?" >> /var/log/kh-backup.log' EXIT
# el trabajo propiamente dicho
Con eso tienes tres pruebas en lugar de una: la línea CRON en el journal (cron lo ha iniciado), la línea final en tu archivo de log (el script ha llegado hasta el final) y el código de salida (ha terminado limpiamente). Solo cuando las tres coinciden, el job funciona.
Si un job puede durar más que su propio intervalo, protégelo además contra solapamientos. Si no, en algún momento arrancan diez instancias en paralelo y tumban el servidor:
*/5 * * * * /usr/bin/flock -n /var/lock/kh-sync.lock /usr/local/bin/sync.sh
flock -n termina de inmediato si ya hay una instancia en marcha. La herramienta está en util-linux y viene en los cuatro sistemas.
@reboot y por qué systemd suele ser mejor
Con @reboot se puede ejecutar un comando al arrancar. Además existen @daily, @hourly, @weekly, @monthly y @yearly, que sustituyen cada uno a los cinco campos de tiempo.
@reboot /usr/local/bin/start-app.sh
Parece cómodo y tiene tres debilidades serias:
- El momento no es "después del arranque", sino "cuando cron arranca". Que la red, la base de datos o un punto de montaje estén listos en ese instante es pura suerte. El apaño habitual es un
sleep 30por delante, lo que solo aplaza el problema. - Un reinicio del servicio cron vuelve a disparar @reboot. Un
systemctl restart cron, por ejemplo tras una actualización de paquetes, arranca tu aplicación una segunda vez aunque la primera siga en marcha. - No hay supervisión. Ni código de salida, ni reinicio tras una caída, ni estado.
Todo lo que deba ejecutarse de forma permanente corresponde a un servicio de systemd, no a un cron job. Para tareas recurrentes, un timer es la mejor opción. Bastan dos archivos:
[Unit]
Description=KernelHost Backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
[Unit]
Description=KernelHost Backup diario
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
RandomizedDelaySec=900
[Install]
WantedBy=timers.target
Se activa el timer, no el servicio:
systemctl daemon-reload
systemctl enable --now kh-backup.timer
systemctl list-timers kh-backup.timer
Las tres ventajas decisivas frente a cron: Persistent=true recupera una ejecución perdida después del siguiente arranque, mientras que cron la salta sin decir nada. El código de salida acaba en systemctl status kh-backup.service, así que ves sin logging propio si ha funcionado. Y la salida completa está disponible con journalctl -u kh-backup.service, sin redirección y sin correo. Por cierto, la ruta de búsqueda en systemd es más generosa que la de cron e incluye por defecto también /usr/local/bin, aunque sin añadir nada propio sigue quedándose corta.
Para tareas de arranque sustituyes @reboot por un servicio con dependencias claras:
[Unit]
After=network-online.target
Wants=network-online.target
Así tu job se ejecuta con garantía solo cuando la red está realmente levantada. Encontrarás más sobre las units y su estructura en crear un servicio de systemd.
Zona horaria, UTC y el horario de verano
cron calcula siempre en la zona horaria del sistema tomada de /etc/localtime. En muchos servidores y en casi todas las imágenes cloud eso es UTC. Un job a las 0 3 * * * se ejecuta entonces en verano a las 05:00, hora de verano de Europa Central, y no a las 03:00. Comprueba primero a qué te enfrentas:
readlink -f /etc/localtime
timedatectl show -p Timezone --value
date
date -u
readlink -f /etc/localtime nombra la ruta dentro de /usr/share/zoneinfo y con ella la zona realmente vigente, por ejemplo /usr/share/zoneinfo/Etc/UTC o /usr/share/zoneinfo/Europe/Vienna. Funciona en las cuatro versiones y también allí donde systemd no está en marcha. timedatectl show -p Timezone --value da la misma información de forma corta y legible por máquina, pero requiere systemd.
Lo que deberías quitarte de encima es mirar en /etc/timezone. Debian 13 ya no entrega ese archivo, un cat /etc/timezone termina allí con cat: /etc/timezone: No such file or directory, y tampoco una instalación de tzdata lo devuelve. En Debian 12, Ubuntu 24.04 y Ubuntu 22.04 todavía existe, así que la respuesta varía según la versión. Determinante es en todo caso únicamente el enlace simbólico /etc/localtime: un valor escrito a mano en /etc/timezone no cambia nada en la zona horaria del sistema y, por tanto, tampoco nada en el momento de disparo de tus jobs.
Puedes cambiar la zona horaria del sistema en cualquier momento; después deberías reiniciar cron para que el servicio adopte el cambio con seguridad:
timedatectl set-timezone Europe/Vienna
systemctl restart cron
En sistemas sin systemd en marcha estableces el enlace simbólico directamente, el resultado es el mismo y se puede verificar al instante con readlink -f /etc/localtime:
ln -sf /usr/share/zoneinfo/Europe/Vienna /etc/localtime
Ahora el punto que en muchas guías está mal: el cron de Debian y Ubuntu no conoce CRON_TZ. Esa variable viene de cronie, el cron de Red Hat, Fedora y AlmaLinux. En Debian 13, Debian 12, Ubuntu 24.04 y Ubuntu 22.04 no existe una zona horaria por usuario ni por crontab. Si pones ahí TZ=Europe/Vienna en la crontab, eso afecta exclusivamente al entorno de los comandos ejecutados, así que un date dentro del script muestra la hora de Viena. El momento de disparo en sí queda totalmente intacto y se sigue rigiendo por la zona horaria del sistema. Quien pasa esto por alto tiene un job que parece bien configurado y que aun así se ejecuta con dos horas de desfase.
Quedan tres caminos limpios: ajustar la zona horaria del sistema, convertir tú mismo las horas a UTC, o cambiar a un timer de systemd, que acepta una zona horaria directamente en la planificación. Se puede comprobar sin riesgo:
systemd-analyze calendar "Mon..Fri 03:00 Europe/Vienna"
La salida indica el próximo disparo como una fecha concreta. Es la comprobación más fiable que puedes hacer antes de activar nada.
Sobre el horario de verano, un consejo práctico: no planifiques jobs entre las 02:00 y las 03:00. En marzo esa hora no existe, en octubre existe dos veces. Según el job, eso significa una ejecución perdida o una duplicada, ambas una vez al año y ambas difíciles de reproducir. Las 01:30 o las 03:30 son alternativas discretas. Con los timers de systemd ayuda además Persistent=true, para que una ejecución perdida se recupere.
Búsqueda rápida de fallos en siete pasos
Si un cron job no se ejecuta, ve por esta lista en orden. Cubre prácticamente todos los casos.
- ¿Se está ejecutando el servicio?
systemctl status cron. Sin servicio no hay job. - ¿Ha llegado la entrada?
crontab -lpara jobs de usuario, si no, mira el archivo en/etc/cron.d/. Comprueba el nombre de archivo sin punto, el modo 0644, el propietario root y el salto de línea final. - ¿Lo ha iniciado cron siquiera?
journalctl -t CRON --since today. Si falta la línea CMD, el problema está en la planificación o en el archivo, no en el script. - ¿El número de campos es correcto? Cinco campos en la crontab de usuario, seis en
/etc/cron.dy/etc/crontab. - ¿Rutas absolutas? Introduce cada comando y cada script con la ruta completa, y averigua antes esa ruta con
command -ven lugar de escribirla a mano. - ¿Entorno comprobado? Añade una sola vez
* * * * * /usr/bin/env > /tmp/cron-env.txt 2>&1, espera un minuto y compara. - Probar en el contexto de cron. No ejecutes el script en tu shell, sino con un entorno vacío:
env -i PATH=/usr/bin:/bin /bin/sh -c '/usr/local/bin/backup.sh'. La ruta de búsqueda la indicas a propósito.env -i /bin/shpor sí solo vacía el entorno, pero dash establece después su propia ruta por defecto/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin, y esa es más generosa que la de cron. Justo los errores de los que trata este artículo quedarían así sin detectar. Si la llamada falla, has encontrado la causa, sin esperar al siguiente momento de disparo.
El último punto es el más valioso. Casi todo cron job que "inexplicablemente" no funciona falla de forma reproducible en cuanto se inicia con un entorno vacío. Así, un misterio que solo aparece cada 24 horas se convierte en un fallo que puedes arreglar en diez segundos.
Quien hace backups con regularidad por cron job debería asegurar además el sistema de destino. Encontrarás indicaciones adecuadas en nuestro artículo sobre la protección de un servidor Linux.
Preguntas frecuentes
¿Por qué mi script funciona en la shell, pero no como cron job?
¿Qué significa el mensaje No MTA installed, discarding output?
¿Debian o Ubuntu admiten la variable CRON_TZ?
¿Por qué se ignora mi archivo en /etc/cron.d?
¿Dónde encuentro los logs de cron en Debian 12 y 13?
¿Una línea CMD en el log demuestra que el job tuvo éxito?
¿Debería usar @reboot o un servicio de systemd?
2026 KernelHost GmbH. Todos los derechos reservados. Esta guía está protegida por derechos de autor. Su publicación en otros sitios web, aunque sea de forma parcial o modificada, no está permitida sin nuestro consentimiento por escrito. Las citas con indicación de la fuente y un enlace son muy bienvenidas.

