Cómo puedo crear un crontab a través de un script


Necesito agregar un trabajo cron a través de un script que corro para configurar un servidor. Actualmente estoy usando Ubuntu. Puedo usar crontab -e pero eso abrirá un editor para editar el crontab actual. Quiero hacer esto programáticamente.

¿Es posible hacerlo?

Author: miku, 2011-02-03

11 answers

Los trabajos Cron generalmente se almacenan en un archivo por usuario bajo /var/spool/cron

Lo más simple que puede hacer es probablemente crear un archivo de texto con el trabajo configurado, luego copiarlo a la carpeta cron spool y asegurarse de que tiene los permisos correctos.

 7
Author: Jason Stelzer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-03 22:22:03

Aquí hay una línea que no usa/requiere que el nuevo trabajo esté en un archivo:

(crontab -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args") | crontab -

El 2>/dev/null es importante para que no reciba el mensaje no crontab for username que algunos *nixes producen si actualmente no hay entradas crontab.

 247
Author: Joe Casadonte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-08 21:30:49

Para los crontabs de usuario (incluyendo root), puedes hacer algo como:

crontab -l -u user | cat - filename | crontab -u user -

Donde el archivo llamado "filename" contiene elementos para anexar. También puede hacer manipulación de texto usando sed u otra herramienta en lugar de cat. Debe usar el comando crontab en lugar de modificar directamente el archivo.

Una operación similar sería:

{ crontab -l -u user; echo 'crontab spec'; } | crontab -u user -

Si está modificando o creando crontabs del sistema, estos pueden ser manipulados como lo haría con los archivos de texto ordinarios. Se almacenan en el /etc/cron.d, /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly los directorios y los archivos /etc/crontab y /etc/anacrontab.

 49
Author: Dennis Williamson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-18 15:25:20

En Ubuntu y muchas otras distribuciones, usted puede poner un archivo en el directorio /etc/cron.d que contiene una sola línea con una entrada válida crontab. No es necesario añadir una línea a un archivo existente.

Si solo necesita algo para ejecutarse diariamente, simplemente coloque un archivo en /etc/cron.daily. Del mismo modo, también puede soltar archivos en /etc/cron.hourly, /etc/cron.monthly, y /etc/cron.weekly.

 23
Author: IvanGoneKrazy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-02 21:59:48

Los archivos Crontab son simplemente archivos de texto y como tales pueden ser tratados como cualquier otro archivo de texto. El propósito del comando crontab es hacer que la edición de archivos crontab sea más segura. Cuando se edita a través de este comando, el archivo se comprueba si hay errores y solo se guarda si no hay ninguno.

crontab [path to file] se puede usar para especificar un crontab almacenado en un archivo. Al igual que crontab -e, esto solo instalará el archivo si está libre de errores.

Por lo tanto, un script puede escribir directamente archivos cron tab, o escribirlos a un archivo temporal y cargarlos con el comando crontab [path to temp file]. Escribir directamente ahorra tener que escribir un archivo temporal, pero también evita la comprobación de seguridad.

 14
Author: cledoux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-22 22:22:54

Una respuesta aún más simple a tu pregunta sería:

echo "0 1 * * * /root/test.sh" | tee -a /var/spool/cron/root

Puede configurar cronjobs en servidores remotos de la siguiente manera:

#!/bin/bash
servers="srv1 srv2 srv3 srv4 srv5"
for i in $servers
  do
  echo "0 1 * * * /root/test.sh" | ssh $i " tee -a /var/spool/cron/root"
done

En Linux, la ubicación predeterminada del archivo crontab es /var/spool/cron/. Aquí puede encontrar los archivos crontab de todos los usuarios. Solo necesita agregar su entrada cronjob al archivo del usuario respectivo. En el ejemplo anterior, el archivo crontab del usuario root se anexa con un cronjob para ejecutar /root/test.sh todos los días a la 1 AM.

 11
Author: ganesh pathak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-30 19:33:09

Como una corrección a los que sugieren crontab -l | crontab -: Esto no funciona en todos los sistemas. Por ejemplo, tuve que agregar un trabajo al crontab raíz en docenas de servidores que ejecutaban una versión antigua de SUSE (no pregunte por qué). Las viejas susEs anteponen líneas de comentarios a la salida de crontab -l, haciendo que crontab -l | crontab - no sea idempotente (Debian reconoce este problema en la página de manual de crontab y parcheó su versión de Vixie Cron para cambiar el comportamiento predeterminado de crontab -l).

Para editar crontabs mediante programación en sistemas donde crontab -l añade comentarios, puedes intentar lo siguiente:

EDITOR=cat crontab -e > old_crontab; cat old_crontab new_job | crontab -

EDITOR=cat le dice a crontab que use cat como editor (no el vi predeterminado habitual), que no cambia el archivo, sino que lo copia a stdout. Esto todavía podría fallar si crontab - espera entrada en un formato diferente de lo que crontab -e produce. No intente reemplazar el crontab - final con crontab -e - no funcionará.

 2
Author: user2845840,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-16 20:32:31

Bien /etc/crontab solo un archivo ascii, por lo que lo más simple es simplemente

 echo "*/15 * * * *   root     date" >> /etc/crontab

Que agregará un trabajo que le enviará un correo electrónico cada 15 minutos. Ajuste a gusto, y pruebe a través de grep u otros medios si la línea ya se agregó para hacer que su script sea idempotente.

En Ubuntu et al, también puede colocar archivos en /etc/cron.*, lo que es más fácil de hacer y probar---además de que no se mete con archivos de configuración (del sistema) como /etc/crontab.

 1
Author: Dirk Eddelbuettel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-02 21:55:38

He escrito una herramienta de implementación de crontab en python: https://github.com/monklof/deploycron

pip install deploycron

Instalar su crontab es muy fácil, esto fusionará el crontab en el crontab existente del sistema.

from deploycron import deploycron
deploycron(content="* * * * * echo hello > /tmp/hello")
 1
Author: monklof,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-24 07:51:55

Aquí está cómo modificar cron una entrada sin editar directamente el archivo cron (que está mal visto).

crontab -l -u <user> | sed 's/find/replace/g' | crontab -u <user> -

Si desea eliminar una entrada cron, use esto:

crontab -l -u <user> | sed '/find/d' | crontab -u <user> -

Me doy cuenta de que esto no es lo que gaurav estaba pidiendo, pero ¿por qué no tener todas las soluciones en un solo lugar?

 1
Author: Brian Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-09 17:47:08

(No tengo suficiente reputación para comentar, así que estoy agregando at como respuesta: siéntase libre de agregarlo como comentario junto a su respuesta)

El one-liner de Joe Casadonte es perfecto, excepto si se ejecuta con set -e, es decir, si su script está configurado para fallar por error, y si todavía no hay cronjobs. En ese caso, el one-liner NO creará el cronjob, pero NO detendrá el script. El fracaso silencioso puede ser muy engañoso.

La razón es que crontab -l devuelve con un código de retorno 1, haciendo que el comando posterior (el echo) no se ejecute... así no se crea el cronjob. Pero como se ejecutan como un subproceso (debido a los paréntesis) no detienen el script.

(Curiosamente, si ejecuta el mismo comando de nuevo, funcionará: una vez que haya ejecutado crontab - una vez, crontab -l todavía no genera nada, pero ya no devuelve un error (ya no recibe el mensaje no crontab for <user>). Así que el siguiente echo se ejecuta y el se crea crontab)

En cualquier caso, si se ejecuta con set -e, la línea debe ser:

(crontab -l 2>/dev/null || true; echo "*/5 * * * * /path/to/job -with args") | crontab -
 0
Author: Faria,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-24 11:39:10