web-dev-qa-db-fra.com

Comment créer une tâche cron en utilisant Bash automatiquement sans l'éditeur interactif?

Crontab a-t-il un argument pour la création de tâches cron sans utiliser l'éditeur (crontab -e). Si oui, quel serait le code créer une tâche cron à partir d'un script Bash?

313
Raúl Roa

Vous pouvez ajouter à la crontab comme suit:

#write out current crontab
crontab -l > mycron
#echo new cron into cron file
echo "00 09 * * 1-5 echo hello" >> mycron
#install new cron file
crontab mycron
rm mycron

Explication de la ligne de cron

* * * * * "command to be executed"
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)

Source nixCraft .

455
dogbane

Vous pourrez peut-être le faire à la volée

crontab -l | { cat; echo "0 0 0 0 0 some entry"; } | crontab -

crontab -l répertorie les tâches crontab actuelles, cat l’imprime, echo imprime la nouvelle commande et crontab - ajoute tous les éléments imprimés dans le fichier crontab. Vous pouvez voir l'effet en faisant un nouveau crontab -l.

273
TheBonsai

Ce fichier plus court ne nécessite aucun fichier temporaire, il est insensible aux insertions multiples et vous permet de modifier la planification d’une entrée existante.

Disons que vous avez ces:

croncmd="/home/me/myfunction myargs > /home/me/myfunction.log 2>&1"
cronjob="0 */15 * * * $croncmd"

Pour l'ajouter à la crontab, sans duplication:

( crontab -l | grep -v -F "$croncmd" ; echo "$cronjob" ) | crontab -

Pour le supprimer de la crontab quel que soit son planning actuel:

( crontab -l | grep -v -F "$croncmd" ) | crontab -

Remarques:

  • grep -F correspond littéralement à la chaîne, car nous ne voulons pas l'interpréter comme une expression régulière
  • Nous ignorons également la planification du temps et ne cherchons que la commande. Par ici; l'horaire peut être modifié sans risque d'ajouter une nouvelle ligne à la crontab
63
MoonCactus

Merci à tous pour votre aide. En assemblant ce que j'ai trouvé ici et ailleurs, j'ai trouvé ceci:

Le code

command="php $INSTALL/indefero/scripts/gitcron.php"
job="0 0 * * 0 $command"
cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -

Je ne pouvais pas comprendre comment éliminer le besoin des deux variables sans me répéter.

command est évidemment la commande que je veux planifier. job prend $command et ajoute les données de planification. J'avais besoin des deux variables séparément dans la ligne de code qui fait le travail.

Détails

  1. Merci à duckyflip, j’utilise cette petite chose de redirection (<(*command*)) pour transformer le résultat de crontab -l en entrée de la commande fgrep.
  2. fgrep filtre ensuite toutes les correspondances de $command (option -v) sans tenir compte de la casse (option -i).
  3. Encore une fois, le petit objet de redirection (<(*command*)) est utilisé pour transformer le résultat en entrée pour la commande cat.
  4. La commande cat reçoit également echo "$job" (explicite), encore une fois, via l'utilisation de la fonction de redirection (<(*command*)).
  5. Ainsi, la sortie filtrée de crontab -l et le simple echo "$job", combinés, sont dirigés ('|') vers crontab - pour être finalement écrits.
  6. Et ils ont tous vécu heureux pour toujours!

En un mot:

Cette ligne de code filtre toutes les tâches cron correspondant à la commande, puis écrit les tâches cron restantes avec la nouvelle, agissant comme une fonction "ajouter" ou "mettre à jour" . est d’échanger les valeurs des variables command et job.

37
Stoutie

EDIT (écrasement fixe):

cat <(crontab -l) <(echo "1 2 3 4 5 scripty.sh") | crontab -
24
duckyflip

Il y a eu beaucoup de bonnes réponses concernant l'utilisation de crontab, mais aucune méthode plus simple, telle que l'utilisation de cron.

Utiliser cron tirerait parti des fichiers système et des répertoires situés à /etc/crontab, /etc/cron.daily,weekly,hourly ou /etc/cron.d/:

cat > /etc/cron.d/<job> << EOF
Shell=/bin/bash 
PATH=/sbin:/bin:/usr/sbin:/usr/bin 
MAILTO=root HOME=/  
01 * * * * <user> <command>
EOF

Dans l'exemple ci-dessus, nous avons créé un fichier dans /etc/cron.d/, fourni les variables d'environnement permettant à la commande de s'exécuter correctement et fourni la variable user pour la commande, ainsi que la variable command. Ce fichier ne doit pas être exécutable et le nom ne doit contenir que des caractères alphanumériques et des traits d'union (plus de détails ci-dessous).

Pour donner une réponse complète cependant, regardons les différences entre crontab et cron/crond:

crontab -- maintain tables for driving cron for individual users

Pour ceux qui souhaitent exécuter le travail dans le contexte de leur utilisateur sur le système, utiliser crontab peut sembler parfaitement logique.

cron -- daemon to execute scheduled commands

Pour ceux qui utilisent la gestion de la configuration ou souhaitent gérer les travaux d'autres utilisateurs, dans ce cas, nous devrions utiliser cron.

Un extrait rapide de la page de manuel vous donne quelques exemples de tâches à ne pas faire:

/ etc/crontab et les fichiers dans /etc/cron.d doivent appartenir à root et ne doivent pas être en groupe, ni inscriptibles. Contrairement à la zone de spoule, les fichiers sous /etc/cron.d ou les fichiers sous /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly et /etc/cron.monthly peuvent également être des liens symboliques, à condition que le lien symbolique et le fichier qu’il désigne soient la propriété de root. Les fichiers sous /etc/cron.d n'ont pas besoin d'être exécutables, alors que les fichiers sous /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly et /etc/cron.monthly le sont, comme ils sont exécutés par les run-parts (voir run-parts (8) pour plus d'informations).

Source:http://manpages.ubuntu.com/manpages/trusty/man8/cron.8.html

La gestion de crons de cette manière est plus facile et plus évolutive du point de vue du système, mais ne sera pas toujours la meilleure solution.

9
Mike Mackintosh

Il y a de fortes chances que vous automatisiez cela et que vous ne souhaitiez pas qu'un seul travail soit ajouté deux fois . Dans ce cas, utilisez:

__cron="1 2 3 4 5 /root/bin/backup.sh"
cat <(crontab -l) |grep -v "${__cron}" <(echo "${__cron}")

Cela ne fonctionne que si vous utilisez BASH. Je ne connais pas la syntaxe DASH (sh) correcte.

Update: Cela ne fonctionne pas si l'utilisateur ne dispose pas encore d'une crontab. Un moyen plus fiable serait: 

(crontab -l ; echo "1 2 3 4 5 /root/bin/backup.sh") | sort - | uniq - | crontab - 

Alternativement, si votre distribution le supporte, vous pouvez également utiliser un fichier séparé: 

echo "1 2 3 4 5 /root/bin/backup.sh" |Sudo tee /etc/crond.d/backup

Trouvé ceux dans une autre SO question .

7
kvz

Une variante qui n'édite que crontab si la chaîne désirée n'y est pas trouvée:

CMD="/sbin/modprobe fcpci"
JOB="@reboot $CMD"
TMPC="mycron"
grep "$CMD" -q <(crontab -l) || (crontab -l>"$TMPC"; echo "$JOB">>"$TMPC"; crontab "$TMPC")
5
Gerald Schade

Pour une belle création rapide et sale/remplacement d'une crontab avec un script BASH, j'ai utilisé cette notation:

crontab <<EOF
00 09 * * 1-5 echo hello
EOF
4
Gibbsoft

Si vous utilisez le Vixie Cron, par exemple sur la plupart des distributions Linux, vous pouvez simplement mettre un fichier dans /etc/cron.d avec le fichier de travail individuel.

Cela ne fonctionne que pour root bien sûr. Si votre système le permet, vous devriez y voir plusieurs exemples. (Notez le nom d'utilisateur inclus dans la ligne, dans la même syntaxe que l'ancien/etc/crontab)

Il est regrettable que cron n’ait aucun moyen de gérer cela en tant qu’utilisateur normal et que tant d’implémentations de cron n’ont aucun moyen de le gérer.

3
chuck

Voici une fonction bash pour ajouter une commande à crontab sans duplication

function addtocrontab () {
  local frequency=$1
  local command=$2
  local job="$frequency $command"
  cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -
}
addtocrontab "0 0 1 * *" "echo hello"
1
Klas Mellbourn

Script Bash pour l'ajout d'un travail cron sans l'éditeur interactif . Le code ci-dessous permet d'ajouter un travail cron à l'aide de fichiers linux.

#!/bin/bash

cron_path=/var/spool/cron/crontabs/root

#cron job to run every 10 min.
echo "*/10 * * * * command to be executed" >> $cron_path

#cron job to run every 1 hour.
echo "0 */1 * * * command to be executed" >> $cron_path
1
akash
CRON="1 2 3 4 5 /root/bin/backup.sh" 
cat < (crontab -l) |grep -v "${CRON}" < (echo "${CRON}")

ajoute le paramètre -w à la commande grep exacte, sans le paramètre -w L'ajout du cronjob "testing" entraîne la suppression du travail cron "testing123"

fonction de script pour ajouter/supprimer des tâches cron. aucune entrée en double:

cronjob_editor () {         
# usage: cronjob_editor '<interval>' '<command>' <add|remove>

if [[ -z "$1" ]] ;then printf " no interval specified\n" ;fi
if [[ -z "$2" ]] ;then printf " no command specified\n" ;fi
if [[ -z "$3" ]] ;then printf " no action specified\n" ;fi

if [[ "$3" == add ]] ;then
    # add cronjob, no duplication:
    ( crontab -l | grep -v -F -w "$2" ; echo "$1 $2" ) | crontab -
Elif [[ "$3" == remove ]] ;then
    # remove cronjob:
    ( crontab -l | grep -v -F -w "$2" ) | crontab -
fi 
} 
cronjob_editor "$1" "$2" "$3"

testé:

$ ./cronjob_editor.sh '*/10 * * * *' 'echo "this is a test" > export_file' add
$ crontab  -l
$ */10 * * * * echo "this is a test" > export_file
1
speefak

Ainsi, dans Debian, Ubuntu et de nombreuses distributions similaires basées sur Debian ...

Il existe un mécanisme de concaténation des tâches périodiques qui prend un fichier de configuration, les regroupe et les ajoute à votre service cron en cours d'exécution.

Vous pouvez placer un fichier sous /etc/cron.d/somefilename où nom_fichier est ce que vous voulez.

Sudo echo "0,15,30,45 * * * * ntpdate -u time.nist.gov" >> /etc/cron.d/vmclocksync

Démontons ceci:

Sudo - parce que vous avez besoin de privilèges élevés pour modifier les configurations cron dans le répertoire/etc

echo - un véhicule pour créer une sortie sur sortie standard. printf, cat ... fonctionnerait aussi bien

"- utilisez une citation double au début de votre chaîne, vous êtes un professionnel

0,15,30,45 * * * * - le programme standard d'exécution de Cron, celui-ci s'exécute toutes les 15 minutes

ntpdate -u time.nist.gov - la commande que je veux exécuter

"- parce que mes premières guillemets doubles ont besoin d'un ami pour fermer la ligne en sortie

>> - la double redirection est ajoutée à la place des écrasements *

/etc/cron.d/vmclocksync - vmclocksync est le nom du fichier que j'ai choisi. Il se trouve dans /etc/cron.d/


* Si nous utilisions la> redirection, nous pourrions garantir que nous n'avions qu'une entrée de tâche. Mais nous risquerions de supprimer toute autre règle d'un fichier existant. Vous pouvez décider vous-même si une éventuelle destruction avec> est correcte ou des doublons possibles avec >> sont pour vous. Alternativement, vous pouvez faire quelque chose de compliqué ou de compliqué pour vérifier si le nom de fichier existe, s'il contient quoi que ce soit et si vous ajoutez un type de duplicata - mais, j'ai des choses à faire et je ne peux pas le faire pour vous maintenant.

0
BradChesney79

fonction de script pour ajouter des tâches cron. vérifier les entrées en double, les expressions utilisables *> "

cronjob_creator () {         
# usage: cronjob_creator '<interval>' '<command>'

  if [[ -z $1 ]] ;then
    printf " no interval specified\n"
Elif [[ -z $2 ]] ;then
    printf " no command specified\n"
else
    CRONIN="/tmp/cti_tmp"
    crontab -l | grep -vw "$1 $2" > "$CRONIN"
    echo "$1 $2" >> $CRONIN
    crontab "$CRONIN"
    rm $CRONIN
fi
}

testé:

$ ./cronjob_creator.sh '*/10 * * * *' 'echo "this is a test" > export_file'
$ crontab  -l
$ */10 * * * * echo "this is a test" > export_file

source: mon cerveau;)

0
user8555334

Ma solution préférée à ceci serait la suivante:

(crontab -l | grep . ; echo -e "0 4 * * * myscript\n") | crontab -

Cela garantira que vous gérez correctement la nouvelle ligne vierge en bas. Pour éviter les problèmes avec crontab, vous devez généralement terminer le fichier crontab par une nouvelle ligne vierge. Et le script ci-dessus s'assure qu'il supprime d'abord toutes les lignes vides avec le "grep". partie, puis ajoutez une nouvelle ligne vide à la fin avec le "\ n" à la fin du script. Cela évitera également d'obtenir une ligne vierge au-dessus de votre nouvelle commande si votre fichier crontab existant se termine par une ligne vierge.

0
gsus

Non, il n'y a pas d'option dans crontab pour modifier les fichiers cron.

Vous devez: prendre le fichier cron actuel (crontab -l> newfile), le modifier et mettre le nouveau fichier en place (crontab newfile).

Si vous connaissez Perl, vous pouvez utiliser ce module Config :: Crontab .

LLP, Andrea

0
andcoz
echo "0 * * * * docker system Prune --force >/dev/null 2>&1" | Sudo tee /etc/cron.daily/dockerprune
0
user11547308