0 votos

El uso de tar en crontab hace que utilice múltiples procesos que consumen toda la cpu

La siguiente línea es la única línea en crontab :

* 13 * * * sh /Users/gentaliaru/Dropbox/work/scripts/backup.sh >/tmp/stdout.log 2>/tmp/stderr.log

Y el contenido de script es

rm -rf /Volumes/X5/backup/git.tar.tz
tar -cvzf /Volumes/X5/tmp/git.tar.tz /Users/gentaliaru/ws/git/
terminal-notifier -message "git Backup is complete" -title "Backup notifier"

Tan pronto como cron se inicia después de 10-20 segundos iniciará 10+ procesos de bsdtar que nunca terminarán. Pero si inicio el mismo comando manualmente entonces termina normalmente en 5 minutos más o menos.

Tuve problemas similares antes de la actualización de MacOS Monterey.

1voto

* 13 * * * sh /Users/gentaliaru/Dropbox/work/scripts/backup.sh >/tmp/stdout.log 2>/tmp/stderr.log

Esta tarea cron comenzará a las 13:00 UTC y se ejecutará cada minuto . Según tu nota "suele tardar unos 5 minutos" cron está iniciando cada minuto un nuevo trabajo antes de que el último haya terminado. De hecho, es una especie de bucle.

La primera * tiene que ser sustituido por 0 para iniciar el trabajo todos los días a las 13:00 horas sólo una vez:

0 13 * * * sh /Users/gentaliaru/Dropbox/work/scripts/backup.sh >/tmp/stdout.log 2>/tmp/stderr.log >/dev/null 2>&1

Aparte del tema del cron, vale la pena considerar los siguientes consejos. Muestra cómo mejorar la robustez y la notificación (incluso para los trabajos fallidos) para su trabajo cron.

Compruebe siempre primero los recursos (archivos, ruta, etc.)

Un escollo común con cron son los recursos perdidos (archivos o rutas) durante la ejecución de un trabajo.

Por lo tanto, un mejor enfoque es especificar siempre las rutas completas y realizar algunas comprobaciones si los archivos y directorios existen. Todo el script debería tener este aspecto para manejar adecuadamente las rutas y archivos existentes/no existentes:

#!/bin/sh

mntPoint="$(/usr/sbin/diskutil info /Volumes/X5/ | /usr/bin/grep 'Mount Point' |  /usr/bin/tr -s ' ' | /usr/bin/cut -d ' ' -f 4)"
if [ $mntPoint != "/Volumes/X5" ]
  then
    /usr/bin/osascript -e 'display notification "/Volumes/X5 has not been mounted" with title "Cron job aborted"'
    exit;
fi

[[ -f '/Volumes/X5/backup/git.tar.tz' ]] && /bin/rm -rf '/Volumes/X5/backup/git.tar.tz'
[[ ! -d '/Volumes/X5/backup' ]] && mkdir '/Volumes/X5/backup'

if /usr/bin/tar -czf /Volumes/X5/backup/git.tar.tz /Users/gentaliaru/ws/git/ 2> /Volumes/X5/backup/.tar.log
  then
    /usr/bin/osascript -e "display notification \"Backup written to /Volumes/X5/backup/git.tar.tz\" with title \"Cron job successfully completed\""
else
    # do not use /usr/bin/read as the internal read command is required!
    read errMsg < /Volumes/X5/backup/.tar.log
    /usr/bin/osascript -e "display notification \"$errMsg\" with title \"Cron job failed\""
    # /path/to/terminal-notifier -message "git Backup is complete" -title "Backup notifier"
fi

Explicación

En primer lugar recomiendo convertir el archivo ascii "plano" en un verdadero shell script añadiendo un shebang en la parte superior del archivo.

#!/bin/sh

Compruebe si la unidad de copia de seguridad está correctamente montada

Las líneas 3-8 aseguran que la unidad de respaldo está montada; de lo contrario, lanzan una notificación. Una comprobación con sólo [[ -d /Volumes/X5 ]] no es lo suficientemente fiable, ya que a veces (muy raramente, pero ha sucedido) la ruta de montaje existe pero sin unidad adjunta. Comprobando con diskutil sortear estas rarezas ocasionales.

Entonces, rm -rf /Volumes/X5/backup/git.tar.tz sin comprobar la existencia del archivo es otra trampa. Es mejor comprobar primero la existencia:

[[ -f '/Volumes/X5/backup/git.tar.tz' ]] && /bin/rm -rf '/Volumes/X5/backup/git.tar.tz'

Además, tu script muestra dos rutas diferentes. El comando de eliminación rm en la línea 1 se refiere a /Volumes/X5/backup pero el tar en la línea 2 se refiere a /Volumes/X5/tmp/git.tar.tz . ¿Es esto realmente lo que quieres?

Invocando tar para escribir un archivo en una ruta/subdirectorio inexistente arroja el siguiente error (al menos aquí en HighSierra 10.13.6):

tar: Failed to open '/Volumes/X5/backup/git.tar.tz'

Por lo tanto, compruebe primero la existencia de tar y crearlo si no existe:

[[ ! -d '/Volumes/X5/backup' ]] && mkdir '/Volumes/X5/backup'

La línea 13 realiza finalmente la copia de seguridad y lanza -en caso de éxito- la notificación (línea 15). En caso contrario, se lanza una notificación sobre el fallo (línea 19).

Uso de recursos internos de MacOS para la notificación

Mi ejemplo utiliza recursos internos de MacOS sin necesidad de herramientas de terceros como terminal-notifier . Se hace mediante una línea de AppleScript que es invocada por osascript .

Si desea mantener la solución con terminal-notifier sólo hay que sustituir las líneas (15 y 19) por osascript ) con lo siguiente:

/path/to/terminal-notifier -message "Backup written to /Volumes/X5/backup/git.tar.tz" -title "Cron job successfully completed" # Line 15
/path/to/terminal-notifier -message "${errMsg}" -title "Cron job failed" # Line 19

También es una buena práctica especificar la ruta completa para terminal-notifier . En caso de que sea instalado por Homebrew utilizar algo como /usr/local/bin/terminal-notifier .

Entonces hazlo ejecutable:

chmod u+x /Users/gentaliaru/Dropbox/work/scripts/backup.sh

Sidenode para Homebrew

Las rutas difieren entre las plataformas (consulte la documentación aquí ):

Su /usr/local en MacOS Intel y /opt/homebrew en Silicio de Apple

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X