¿Cómo puedo crear programáticamente un nuevo trabajo cron?


Quiero poder agregar programáticamente un nuevo trabajo cron, ¿cuál es la mejor manera de hacer esto?

De mi investigación , parece que podría volcar el crontab actual y luego agregar uno nuevo, canalizándolo de nuevo en crontab:

(crontab -l ; echo "0 * * * * wget -O - -q http://www.example.com/cron.php") | crontab -

Hay una manera mejor?

Author: DavidM, 2009-03-04

16 answers

Siempre ha funcionado bien para mí.

Debería considerar un script un poco más sofisticado que pueda hacer tres cosas.

  1. Añadir una línea crontab; asegurando que no existía. Agregar cuando ya existe es malo.

  2. Retire la línea crontab. Tal vez sólo advirtiendo si no existía.

  3. Una combinación de las dos características anteriores para reemplazar la línea crontab.

 -8
Author: S.Lott,
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
2009-03-04 14:38:42

La mejor manera si se está ejecutando como root, es soltar un archivo en /etc/cron.d

Si usa un gestor de paquetes para empaquetar su software, simplemente puede colocar archivos en ese directorio y se interpretan como si fueran crontabs, pero con un campo adicional para el nombre de usuario, por ejemplo:

Nombre de archivo: /etc/cron.d/per_minute

Contenido: * * * * * root /bin/sh /home/root/script.sh

 103
Author: MarkR,
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-06-05 21:48:49

La solución de OP tiene un error, podría permitir que las entradas se agreguen dos veces, use a continuación para solucionarlo.

(crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | crontab -
 78
Author: JohnZ,
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-04-17 20:31:39

Para añadir algo a cron

(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | sort | uniq | crontab -

Para eliminar esto de cron

(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | grep -v hupChannel.sh |  sort | uniq | crontab -

La esperanza ayudaría a alguien

 20
Author: user3865482,
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-07-22 16:28:56

Si está planeando hacerlo para un escenario de ejecución única para simplemente wget'ing algo, eche un vistazo a 'at'

 6
Author: Christian Witts,
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
2009-03-04 14:44:20

Simplemente cambie el editor a tee comando:

EDITOR de exportación = "tee"

Echo "0 * * * * /bin / echo 'Hello World '" / crontab-e

 4
Author: Renato Tambellini,
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-06-17 14:15:01

Suponiendo que ya hay una entrada en su crontab, el siguiente comando debería funcionar relativamente bien. Tenga en cuenta que la variable $CMD solo está allí para facilitar la lectura. Ordenar antes de filtrar duplicados es importante, porque uniq solo funciona en líneas adyacentes.

CMD='wget -O - -q http://www.example.com/cron.php"'
(crontab -l ; echo "0 * * * * $CMD") | sort | uniq | crontab -

Si actualmente tiene un crontab vacío, recibirá el siguiente error en stderr:

no crontab for user

Si desea evitar esto, puede agregar un poco de complejidad agregar hacer algo como esto:

(crontab -l ; echo "0 * * * * $CMD") 2>&1 | sed "s/no crontab for $(whoami)//"  | sort | uniq | crontab -
 3
Author: Tim McNamara,
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
2017-10-09 21:41:44

Añadiendo a la respuesta de JohnZ, aquí está la sintaxis para programar como root si eres un sudoer:

(sudo crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | sudo crontab -
 2
Author: BuvinJ,
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-07-24 16:00:23

Man crontab también es útil:

CRONTAB (1)

NOMBRE

   crontab - manipulate per-user crontabs (Dillon's Cron)

SINOPSIS

   crontab file [-u user] - replace crontab from file

   crontab - [-u user] - replace crontab from stdin

   crontab -l [user] - list crontab for user
 1
Author: vitaly.v.ch,
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
2009-03-06 10:41:51
function cronjob_exists($command){

    $cronjob_exists=false;

    exec('crontab -l', $crontab);


    if(isset($crontab)&&is_array($crontab)){

        $crontab = array_flip($crontab);

        if(isset($crontab[$command])){

            $cronjob_exists=true;

        }

    }
    return $cronjob_exists;
}

function append_cronjob($command){

    if(is_string($command)&&!empty($command)&&cronjob_exists($command)===FALSE){

        //add job to crontab
        exec('echo -e "`crontab -l`\n'.$command.'" | crontab -', $output);


    }

    return $output;
}

    append_cronjob('* * * * * curl -s http://localhost/cron/test.php');
 1
Author: RafaSashi,
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-07-14 00:32:11

Esto verificaría para asegurarse de que su comando no existe ya antes de agregarlo.

crontab -l 2>/dev/null | grep -q '/path/to/script' || echo "5 * * * * /path/to/script" | crontab -

Saludos.

 0
Author: Ezra Obiwale,
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-11-11 11:43:22

Piping stdout into crontab no instalé el nuevo crontab para mí en macOS, así que encontré esta solución en su lugar, usando el editor tee en un sub shell:

(EDITOR=tee && (crontab -l ; echo "@daily ~/my-script.sh" ) | uniq - | crontab -e)
 0
Author: Simon Hänisch,
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
2017-08-19 10:33:27

Aquí hay otra forma de un solo revestimiento, que evita duplicados

(crontab -l 2>/dev/null | fgrep -v "*/1 *  *  *  * your_command"; echo "*/1 *  *  *  * your_command") | crontab -

Y aquí hay una manera de hacer la respuesta de JohnZ y evitar el mensaje no crontab for user, o si necesita operar en un entorno de tipo set -eu y no puede hacer que nada devuelva un error (en cuyo caso la parte 2>/dev/null es opcional):

( (crontab -l 2>/dev/null || echo "")  ; echo "0 * * * * your_command") | sort -u - | crontab -

O si quieres dividir las cosas para que sean más legibles:

new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
(echo "$preceding_cron_jobs" ; echo "$new_job") | sort - | uniq - | crontab -

O, opcionalmente, eliminar cualquier referencia a su_command (por ejemplo: si la programación ha cambiado, solo desea que alguna vez cron'ed una vez). En este caso ya no necesitamos uniq (bono añadido, el orden de inserción también se conserva):

new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
preceding_cron_jobs=$(echo "$preceding_cron_jobs" | grep -v your_command )
(echo "$preceding_cron_jobs" ; echo "$new_job") | crontab -
 0
Author: rogerdpack,
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-04-18 15:13:56

La mayoría de las soluciones aquí son para agregar líneas al crontab. Si necesita más control, querrá poder controlar todo el contenido del crontab.

Puede usar tuberías para hacer esto con bastante elegancia.

Para reescribir completamente el crontab, haga

echo "2 2 2 2 2 /bin/echo foobar" |crontab -

Esto debería ser fácil de combinar con otras respuestas descritas aquí como

crontab -l | <something> | tee |crontab -

O, si tiene el contenido en un archivo, es aún más simple

cat <file> |crontab -
 0
Author: Eldamir,
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-06-14 05:54:56

También puede añadir sus tareas a /etc/cron.*/

 -1
Author: vitaly.v.ch,
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
2009-03-06 10:39:28

También puede editar el archivo de texto de la tabla cron directamente, pero su solución parece perfectamente aceptable.

 -2
Author: Alex Fort,
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
2009-03-04 14:36:41