Je dois ajouter un travail cron via un script que je lance pour configurer un serveur. J'utilise actuellement Ubuntu. Je peux utiliser crontab -e
mais cela ouvrira un éditeur pour éditer la crontab actuelle. Je veux le faire par programme.
Est-il possible de le faire?
Les tâches Cron sont généralement stockées dans un fichier par utilisateur sous /var/spool/cron
La chose la plus simple à faire est probablement de simplement créer un fichier texte avec le travail configuré, puis de le copier dans le dossier spool de cron et de s’assurer qu’il dispose des autorisations appropriées.
Voici un one-liner qui n'utilise pas/ne requiert pas que le nouveau travail soit dans un fichier:
(crontab -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args") | crontab -
Le 2>/dev/null
est important pour que vous n'ayez pas le message no crontab for username
que certains * nix produisent s'il n'y a aucune entrée dans la crontab.
Pour les utilisateurs crontabs (y compris root), vous pouvez faire quelque chose comme:
crontab -l -u user | cat - filename | crontab -u user -
où le fichier nommé "nom de fichier" contient des éléments à ajouter. Vous pouvez également manipuler du texte en utilisant sed
ou un autre outil à la place de cat
. Vous devez utiliser la commande crontab
au lieu de modifier directement le fichier.
Une opération similaire serait:
{ crontab -l -u user; echo 'crontab spec'; } | crontab -u user -
Si vous modifiez ou créez des tables de vérification système, celles-ci peuvent être manipulées comme des fichiers texte ordinaires. Ils sont stockés dans les répertoires /etc/cron.d
, /etc/cron.hourly
, /etc/cron.daily
, /etc/cron.weekly
, /etc/cron.monthly
et dans les fichiers /etc/crontab
et /etc/anacrontab
.
Dans Ubuntu et de nombreuses autres distributions, vous pouvez simplement placer un fichier dans le répertoire /etc/cron.d
contenant une seule ligne avec une entrée crontab valide. Pas besoin d'ajouter une ligne à un fichier existant.
Si vous avez juste besoin de quelque chose à exécuter quotidiennement, il suffit de mettre un fichier dans /etc/cron.daily
. De même, vous pouvez également déposer des fichiers dans /etc/cron.hourly
, /etc/cron.monthly
et /etc/cron.weekly
.
Les fichiers Crontab sont simplement des fichiers texte et peuvent donc être traités comme n'importe quel autre fichier texte. La commande crontab
a pour but de rendre l'édition des fichiers crontab plus sûre. Lorsqu'il est modifié via cette commande, le fichier est vérifié pour les erreurs et uniquement enregistré s'il n'y en a pas.
crontab [path to file]
peut être utilisé pour spécifier une crontab stockée dans un fichier. Comme crontab -e
, le fichier ne sera installé que s'il est exempt d'erreur.
Par conséquent, un script peut écrire directement des fichiers à onglet cron ou les écrire dans un fichier temporaire et les charger avec la commande crontab [path to temp file]
. L'écriture directe évite d'avoir à écrire un fichier temporaire, mais évite également le contrôle de sécurité.
Une réponse encore plus simple à votre question serait:
echo "0 1 * * * /root/test.sh" | tee -a /var/spool/cron/root
Vous pouvez configurer des tâches cron sur des serveurs distants comme ci-dessous:
#!/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
Sous Linux, l’emplacement par défaut du fichier crontab
est /var/spool/cron/
. Ici vous pouvez trouver les fichiers crontab
de tous les utilisateurs. Il vous suffit d'ajouter votre entrée cronjob au fichier de l'utilisateur correspondant. Dans l'exemple ci-dessus, le fichier crontab de l'utilisateur root est ajouté à un fichier cronjob pour exécuter /root/test.sh
tous les jours à 1 heure.
Pour corriger ceux qui suggèrent crontab -l | crontab -
: Cela ne fonctionne pas sur tous les systèmes. Par exemple, j'ai dû ajouter un travail à la crontab racine sur des dizaines de serveurs exécutant une ancienne version de SUSE (ne demandez pas pourquoi). Les anciennes versions de SUSE ajoutent des lignes de commentaires à la sortie de crontab -l
, rendant crontab -l | crontab -
non idempotent (Debian reconnaît ce problème dans la page de manuel crontab et corrige sa version de Vixie Cron pour modifier le comportement par défaut de crontab -l
).
Pour éditer les crontabs par programme sur les systèmes où crontab -l
ajoute des commentaires, vous pouvez essayer les solutions suivantes:
EDITOR=cat crontab -e > old_crontab; cat old_crontab new_job | crontab -
EDITOR=cat
indique à crontab d'utiliser cat
comme éditeur (pas le vi habituel par défaut), qui ne change pas le fichier, mais le copie sur stdout. Cela peut toujours échouer si crontab -
attend une entrée dans un format différent de celui que crontab -e
génère. N'essayez pas de remplacer le crontab -
final par crontab -e
- cela ne fonctionnera pas.
Bien /etc/crontab
juste un fichier ascii, le plus simple est de simplement
echo "*/15 * * * * root date" >> /etc/crontab
qui ajoutera un travail qui vous enverra un courriel toutes les 15 minutes. Ajustez à votre goût et testez avec grep
ou un autre moyen si la ligne a déjà été ajoutée pour rendre votre script idempotent.
Sur Ubuntu et al, vous pouvez également déposer des fichiers dans /etc/cron.*
, ce qui est plus facile à faire et à tester - en plus de ne pas jouer avec les fichiers de configuration (système) tels que /etc/crontab
.
Voici comment modifier cron une entrée sans éditer directement le fichier cron (ce qui est mal vu).
crontab -l -u <user> | sed 's/find/replace/g' | crontab -u <user> -
Si vous voulez supprimer une entrée cron, utilisez ceci:
crontab -l -u <user> | sed '/find/d' | crontab -u <user> -
Je réalise que ce n’est pas ce que Gaurav demandait, mais pourquoi ne pas disposer de toutes les solutions au même endroit?
J'ai écrit un outil de déploiement Crontab en python: https://github.com/monklof/deploycron
pip install deploycron
Installer votre crontab est très facile, cela va fusionner la crontab dans la crontab existante du système.
from deploycron import deploycron
deploycron(content="* * * * * echo hello > /tmp/hello")
(Je n'ai pas assez de réputation pour commenter, donc j'ajoute at pour réponse: n'hésitez pas à l'ajouter sous forme de commentaire à côté de sa réponse)
One-Liner de Joe Casadonte est parfait, sauf si vous exécutez avec set -e
, c'est-à-dire si votre script est configuré pour échouer en cas d'erreur et s'il n'y a pas encore de tâches cron. Dans ce cas, one-liner NE créera PAS le travail cron, mais n'arrêtera PAS le script. L'échec silencieux peut être très trompeur.
La raison en est que crontab -l
retourne avec un code retour 1
, ce qui empêche la commande suivante (la echo
) de ne pas être exécutée ... ainsi, le travail cron n'est pas créé. Mais comme ils sont exécutés en tant que sous-processus (à cause de la parenthèse), ils n'arrêtent pas le script.
(Fait intéressant, si vous exécutez à nouveau la même commande, cela fonctionnera: une fois que vous avez exécuté crontab -
une fois, crontab -l
ne génère toujours rien, mais il ne renvoie plus d'erreur (vous ne recevez plus le message no crontab for <user>
). echo
suivant est exécuté et la crontab est créée)
Dans tous les cas, si vous exécutez avec set -e
, la ligne doit être:
(crontab -l 2>/dev/null || true; echo "*/5 * * * * /path/to/job -with args") | crontab -
C'est une approche pour ajouter progressivement le travail cron:
ssh USER_NAME@$PRODUCT_IP Nohup "echo '*/2 * * * * ping -c2 PRODUCT_NAME.com >> /var/www/html/test.html' | crontab -u USER_NAME -"