
Estoy intentando ejecutar un script almacenado en mi directorio personal mediante crontab, pero no funciona. El registro CRON simplemente dice esto cada vez que se ejecuta:
Sep 3 18:30:01 backup CRON[6778]: (root) CMD (/home/hannes/script > /tmp/yc.log)
Sep 3 18:30:01 backup CRON[6777]: (CRON) info (No MTA installed, discarding output)
Tabulador cronológico:
*/1 * * * * /home/hannes/script > /tmp/yc.log
Si intento agregar la extensión de archivo .sh, no cambia nada. El archivo yc.log permanece vacío.
Este es el script que estoy intentando ejecutar (funciona bien si lo ejecuto manualmente):
#!/bin/sh
cp -r -p mnt/main-nas/PATH-TO-FILE mnt/backup-nas/01/temp/server
zip -r mnt/backup-nas/01/1.19_Test.`date +%d.%m.%Y_%H.%M.%S`.zip mnt/backup-nas/01/temp/server
rm -r mnt/backup-nas/01/temp/server
¡Cualquier ayuda es apreciada! :)
Respuesta1
Tu guiónesen realidad se está ejecutando... pero hay un error en alguna parte. Y como no captura stderr
la salida, stderr se envía cron
al usuario que ejecuta el script localmente. (Y fallando también)
La causa principal es esta: su secuencia de comandos solo redirige stdout
a archivos. Sin embargo, muchos scripts y programas que fallan suelen stderr
generar sus mensajes de error. Debe detectarlo agregando 2>&1
al final de la línea de comando que cron
se ejecuta, que también capturará stderr
y registrará los errores en su archivo.
Debido a que no lo detectó anteriormente, stderr se estaba entregando por correo root
, pero debido a que no tiene un MTA local (Agente de transferencia de correo, también conocido como servidor de Protocolo de transporte de correo local (LMTP)) para la entrega local, recibió esos errores cron. . Con la stderr
captura, ahora verá errores y explicará por qué su(s) script(s) no se han ejecutado correctamente.
Una vez que tenga el resultado del error en sus registros, puede depurar aún más su script para determinar qué se debe hacer para "arreglar" las cosas.
Respuesta2
Entonces hubo varios problemas. En primer lugar, olvidé agregar el 2>&1
final de /home/hannes/script > /tmp/yc.log
para que el registro se guardara. Y en segundo lugar, tuve un error tipográfico en mi guión, donde olvidé la primera barra en todas las rutas. Pasó de esto home/hannes/...
a esto /home/hannes/...
. Espero que esto ayude a otras personas que tienen un problema similar y gracias a todos los que respondieron :)
Respuesta3
La respuesta aceptada es correcta y cubre la pregunta planteada. Sin embargo, la información proporcionada en la pregunta indica un problema potencial no relacionado con este script sobre el cual creo que es importante advertir al OP, y explicarlo adecuadamente es demasiado largo para un comentario, por lo que agregaré una respuesta específicamente para cubrir eso.
Aparte del problema del registro, su acuerdo también tiene una condición de carrera potencialmente desagradable. Debido a que el script siempre utiliza el mismo directorio para almacenar los archivos que se van a archivar, si se ejecuta más de una instancia del script al mismo tiempo, es probable que la primera ejecución elimine los archivos en los que las instancias posteriores estén trabajando actualmente, lo que generará más fallas y muy probablemente archivos incompletos (porque los archivos desaparecerán antes de que zip
podamos procesarlos).
Esto se puede resolver de dos maneras: el script en sí debe usar un directorio por invocación o se debe usar el bloqueo de archivos para evitar ejecuciones simultáneas.
El primer método es mucho más sencillo: simplemente puede agregar la fecha al directorio que está utilizando. Se vería así (tenga en cuenta que esto también garantiza que date
solo se llame una vez):
#!/bin/sh
now="$(date +%d.%m.%Y_%H.%M.%S)"
cp -r -p mnt/main-nas/PATH-TO-FILE mnt/backup-nas/01/temp/server/${now}
zip -r mnt/backup-nas/01/1.19_Test.${now}.zip mnt/backup-nas/01/temp/server/${now}
rm -r mnt/backup-nas/01/temp/server/${now}
El enfoque de bloqueo de archivos es un poco más complicado, pero posiblemente más limpio porque también garantiza que no se pueda saturar accidentalmente el sistema con múltiples zip
comandos ejecutándose al mismo tiempo. Esto implica usar un comando llamado flock
(parte del util-linux
paquete en Ubuntu y Debian, que ya estará instalado), y se parece a esto (con comentarios para explicar lo que está pasando):
#!/bin/sh
# All of this gets run in a subshell so we can hold a file descriptor open
# for all the commands. We're using file descriptor 9 here, but any number
# higher than 2 will work.
(
# This flock command is what actually takes the lock. The lock itself
# persists until the file descriptor is closed when the subshell exits.
# The -x means it's an exclusive lock (so only one instance can hold it).
# The -w says to try for that many seconds before failing if something
# else is holding the lock (this is an important safety net to ensure you
# don’t get a long queue of these scripts waiting to run).
# The -n indicates which file descriptor to take the lock on.
flock -x -w 30 -n 9 || exit 1
cp -r -p mnt/main-nas/PATH-TO-FILE mnt/backup-nas/01/temp/server
zip -r mnt/backup-nas/01/1.19_Test.`date +%d.%m.%Y_%H.%M.%S`.zip mnt/backup-nas/01/temp/server
rm -r mnt/backup-nas/01/temp/server
# And this line closes the subshell, and also sets the path to be used for
# the lock file by opening it as file descriptor 9 for the subshell. /run
# is generally the place you want to put stuff like this, because it will
# get cleaned up automatically every time the system reboots.
) 9> /run/backup-nas.lock