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?
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
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 -
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
Si vous envisagez de le faire pour un scénario unique, jetez un œil à 'at'
Changez simplement l’éditeur en tee tee:
export EDITOR="tee"
echo "0 * * * * /bin/echo 'Hello World'" | crontab -e
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 -
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 -
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');
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 -
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
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é.
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 -
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)