web-dev-qa-db-fra.com

Comment puis-je créer par programme un nouveau travail cron?

Je veux pouvoir ajouter par programmation un nouveau travail cron, quelle est la meilleure façon de le faire?

D'après mes recherches , il semble que je pourrais vider la crontab actuelle, puis en ajouter une nouvelle, la redirigeant dans la crontab:

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

Y a-t-il un meilleur moyen?

109
DavidM

La meilleure façon de s’exécuter en tant que root est de déposer un fichier dans /etc/cron.d.

si vous utilisez un gestionnaire de paquets pour empaqueter votre logiciel, vous pouvez simplement déposer des fichiers dans ce répertoire et les interpréter comme s'il s'agissait de crontabs, mais avec un champ supplémentaire pour le nom d'utilisateur, par exemple:

Nom de fichier: /etc/cron.d/per_minute

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

109
MarkR

La solution d'OP a un bogue, elle pourrait permettre l'ajout de deux entrées, utilisez ci-dessous pour corriger.

(crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | crontab -
82
JohnZ

Ajouter quelque chose à cron

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

Pour le supprimer de cron

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

l'espoir aiderait quelqu'un

21
user3865482

Si vous envisagez de le faire pour un scénario unique, jetez un œil à 'at'

6
Christian Witts

Changez simplement l’éditeur en tee tee:

export EDITOR="tee"
echo "0 * * * * /bin/echo 'Hello World'" | crontab -e
5
Renato Tambellini

En supposant qu'il y ait déjà une entrée dans votre crontab, la commande suivante devrait fonctionner relativement bien. Notez que la variable $CMD n’est là que pour la lisibilité. Le tri avant le filtrage des doublons est important, car uniq ne fonctionne que sur les lignes adjacentes.

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

Si vous avez actuellement une crontab vide, vous recevrez le message d'erreur suivant à stderr:

no crontab for user

Si vous voulez éviter cela, vous pouvez ajouter un peu de complexité et faire quelque chose comme ça:

(crontab -l ; echo "0 * * * * $CMD") 2>&1 | sed "s/no crontab for $(whoami)//"  | sort | uniq | crontab -
4
Tim McNamara

Ajoutant à la réponse de JohnZ, voici la syntaxe pour planifier en tant que root si vous êtes un sudoer:

(Sudo crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | Sudo crontab -
2
BuvinJ
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
RafaSashi

La plupart des solutions proposées ici permettent d’ajouter des lignes à la crontab. Si vous avez besoin de plus de contrôle, vous voudrez pouvoir contrôler tout le contenu de la crontab.

Vous pouvez utiliser la tuyauterie pour le faire très élégamment.

Pour réécrire complètement la crontab, faites

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

Cela devrait être facile à combiner avec d'autres réponses décrites ici comme

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

Ou, si vous avez le contenu dans un fichier, c'est encore plus simple

cat <file> |crontab -
1
Eldamir

man crontab est aussi utile:

CRONTAB (1) 

PRÉNOM

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

SYNOPSIS

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

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

   crontab -l [user] - list crontab for user
1
vitaly.v.ch

Cela permettrait de vérifier que votre commande n'existe pas déjà avant de l'ajouter.

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

À votre santé.

1
Ezra Obiwale

Voici une autre manière one-liner, qui évite les doublons

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

Et voici un moyen de faire la réponse de JohnZ et d'éviter le message no crontab for user, ou si vous devez opérer dans un environnement de type set -eu et que rien ne peut renvoyer d'échec (dans ce cas, la partie 2>/dev/null est facultative):

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

Ou si vous voulez séparer les choses pour qu'elles soient plus lisibles:

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

Ou éventuellement supprimer toutes les références à votre_commande (par exemple, si la planification a changé, vous ne voulez la créer jamais une seule fois). Dans ce cas, nous n'avons plus besoin de uniq (bonus supplémentaire, l'ordre d'insertion est également conservé):

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
rogerdpack

Piping stdout dans crontab n'a pas installé la nouvelle crontab pour moi sur macOS. J'ai donc trouvé cette solution à la place, en utilisant l'éditeur tee dans un sous-shell:

(EDITOR=tee && (crontab -l ; echo "@daily ~/my-script.sh" ) | uniq - | crontab -e)
0
Simon Hänisch