Scripts

Quelques scripts pour bien utiliser Linux

Bonnes pratiques pour écrire un script

Dans Linux, un script est un fichier rassemblant une succession de commandes.
Toutes les commandes peuvent être écrites les unes à la suite des autres.
Elles sont exécutées séquentiellement par le shell.

Pour une bonne exécution du script, il est toutefois conseillé de le structurer correctement pour éviter les mauvaises surprises.

Personnellement, je respecte toujours les règles suivantes :

1 - Toujours nommer son script avec l'extension ".sh" (facilite la recherche)

2 - La première ligne d'un script doit toujours indiquer quel interpréteur de commande utiliser, par exemple :
#!/bin/bash
#!/bin/sh
#!/usr/bin/python
#!/usr/bin/php

3 - Renseigner la variable PATH :
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

La variable PATH permet d'indiquer au shell les répertoires où sont situés les commandes externes utilisées.
En console, la variable PATH est initialisée à la connexion ce qui fait qu'il n'est pas nécessaire d'indiquer le chemin complet d'une commande afin de l'exécuter. Si le script est exécuté uniquement en console, il n'est pas nécessaire d'initialiser la variable PATH mais si le script est exécuté via une tâche cron, la variable PATH est inconnue, dans ce cas, toutes les commandes externes utilisées dans le script ne pourront pas être exécutées.

4 - Rediriger la sortie d'erreur standard dans un fichier de log spécifique, par exemple :
exec 2>>/var/log/mon_script_error.log
exec 2>/dev/null (s'il n'est pas nécessaire de "logguer" les différentes erreurs rencontrées)

5 - Terminer le script avec la commande suivante :
exit 0

Exemple avec un script basique :

$ cat mon_script.sh
#!/bin/bash
 
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 
exec 2>/dev/null
 
...
mes commandes
...
 
exit 0

Créer une sauvegarde différentielle

Pour effectuer une sauvegarde différentielle, il faut utiliser le programme rdiff-backup.

Pour l'installer :

$ sudo apt-get install rdiff-backup

Pour créer une sauvegarde différentielle :

Créer un fichier, par exemple sauvegarde_differentielle.sh et y inscrire les deux lignes suivantes

$ cat sauvegarde_differentielle.sh
#!/bin/sh
 
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 
exec 1>>/var/log/sauvegarde_differentielle.log
exec 2>>/var/log/sauvegarde_differentielle_error.log
 
nice -n 19 rdiff-backup /repertoire_a_sauvegarder /destination_de_la_sauvegarde && nice -n 19 rdiff-backup --remove-older-than 1W --force /destination_de_la_sauvegarde
 
exit 0
 
$

Rendre le scripts exécutable

  • nice -n 19 : exécute le programme avec une priorité basse pour éviter que le processeur soit utilisé à 100%
  • rdiff-backup --remove-older-than 1W --force : force la suppression des sauvegardes de plus d'une semaine (1W)

Voir également cette rubrique pour plus de renseignements

Mise à jour des paquets

  • Créer un fichier maj.sh

Ecrire dans le fichier la ligne suivante

 

$ cat maj.sh
#!/bin/sh
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
sudo apt-get update && sudo apt-get upgrade
exit 0

Pour exécuter ce script, taper dans la console

$ $MAJ


Une autre méthode, plus simple, consiste à créer un alias dans le fichier ~/.bashrc.

$ echo "alias maj='sudo apt-get update && sudo apt-get upgrade'" >> ~/.bashrc

Prendre en compte le nouvel alias créé :

$ . ~/.bashrc

Pour l'exécution :

$ maj

Etiquettes: 

Redémarrer un processus automatiquement

Pour surveiller un processus et le redémarrer en cas de plantage, créer une tâche cron exécutée en tant que root avec la commande suivante :

Par exemple, pour le processus DOVECOT (serveur POP / IMAP)

$ pgrep dovecot > /dev/null || { /etc/init.d/dovecot restart ; }

Etiquettes: 

Sauvegarder la liste des sources et des paquets

$ cat sauvegarde.sh
#!/bin/bash
 
####### sauvegarde - Sauvegarde le sources.list et les paquets #######
 
echo
echo "Script de sauvegarde APT'"
echo
 
DATE=`date +%F`
 
if test -d $DATE
    then echo "Le dossier \"$DATE\" existe déjà. Voulez-vous refaire la sauvegarde ? [o/n]"
    read choix
    
    if [ $choix = "n" ]
    then
        echo
        echo "Abandon."
        exit 0
    elif [ $choix = "o" ]
    then
        echo
        echo "Réécriture de la sauvegarde $DATE..."
    else
        echo "Veuillez taper \"o\" ou \"n\"."
        exit 2
    fi
else
    mkdir $DATE
fi
 
( cp /etc/apt/sources.list ./$DATE/sources.$DATE.list && dpkg --get-selections > ./$DATE/paquets.$DATE.list ) \
&& echo "Sauvegarde terminée dans $PWD/$DATE" \
|| echo "Sauvegarde échouée..."
 
exit 0

Etiquettes: 

Restaurer la sauvegarde des sources et des paquets

$ cat restauration.sh
#!/bin/bash
 
####### restauration - Script de restauration APT #######
 
echo
echo "Script de restauration APT"
echo "Une connexion Internet fonctionnelle est requise pour le bon fonctionnement de ce script."
echo
 
##### DEBUT GESTION DES ERREURS #####
 
ls -1 | grep '^[[:digit:]]\{4\}\-[[:digit:]]\{2\}\-[[:digit:]]\{2\}$' > /dev/null
 
if test $? -ne 0
then
    echo "Il n'y a rien à restaurer !"
    exit 2
elif [ ! `whoami` = "root" ]
then
    echo "Il faut être root ... Executez \"sudo !!\"."
    exit 2
elif test $# -ne 1
then
    echo "Il faut un seul paramètre. Tapez \"./restauration sources\" pour restaurer le sources.list ou \"./restauration paquets\" pour restaurer les paquets."
    exit 2
fi
 
##### FIN GESTION DES ERREURS #####
 
##### DEBUT SELECTION D'UNE DATE #####
 
echo
echo "Par défaut le script restaure votre sauvegarde la plus récente. Voulez-vous en restaurer une autre ? [o/n]"
read choix
 
if [ $choix = "n" ] # Si il veut la plus récente, on prend la plus récente en fonction du nom des dossiers de sauvegarde
then
    DATE=`ls -1 | grep '^[[:digit:]]\{4\}\-[[:digit:]]\{2\}\-[[:digit:]]\{2\}$' | tail -n 1`
    echo "La date choisie est $DATE."
elif [ $choix = "o" ] # Sinon on lui demande de rentrer une date
then
    echo "Veuillez entrer la date souhaitée, sous la forme AAAA-MM-JJ : "
    read DATE
    
    if test -d $DATE
    then
        echo "La date choisie est $DATE."
    else
        echo "La date demandée n'existe pas dans les sauvegardes !"
        exit 2
    fi
else
    echo "Veuillez entrer \"o\" ou \"n\"."
    exit 2
fi
 
echo
echo "Est-ce bien ce que vous voulez ? [o/n]" # Confirmation
read choix2
 
if [ $choix2 = "o" ]
then
    echo "Continuons donc !"
    sleep 2 # On dort 2 secondes pour la lisiblité
elif [ $choix2 = "n" ]
then
    echo "Abandon."
    exit 2
else
    echo "Veuillez entrer \"o\" ou \"n\"."
    exit 2
fi
 
echo
 
##### FIN SELECTION D'UNE DATE #####
 
##### DEBUT RESTAURATION #####
 
if test $1 = "sources" # Si on veut restaurer le sources.list
then
    cp /etc/apt/sources.list /etc/apt/sources.list.svgorig.$DATE
    ( cp $DATE/sources.$DATE.list /etc/apt/sources.list && apt-get update ) \
    && (echo ; echo "Restauration du sources.list terminée avec succès.") \
    || (echo ; echo "Restauration du sources.list échouée... Vous n'avez probablement pas les droits d'écriture dans /etc/apt/" ; \
    cp /etc/apt.sources.list.svgorig.$DATE /etc/apt/sources.list && echo "Votre sources.list original a été restauré." ; exit 2)
    
elif test $1 = "paquets" # Si on veut restaurer les paquets
then
    ( dpkg --set-selections < $DATE/paquets.$DATE.list && apt-get update ; apt-get dselect-upgrade ) \
    && (echo ; echo "Restauration des paquets terminée avec succès") \
    || (echo ; echo "Restauration des paquets échouée... Votre connexion Internet est peut-être défaillante." ; exit 2)
    
else
    echo "Paramètre inconnu"
    exit 2
fi
 
exit 0
 
##### FIN RESTAURATION #####

Etiquettes: 

"Explode" version "Bash"

Détail du script

$ nl explode.sh
     1  #!/bin/bash
 
     2  chemin="chemin 1|chemin 2 chemin 2 et demi|chemin 3"
 
     3  #Sauvegarde de la valeur du IFS
     4  #La variable $IFS doit être obligatoirement entre guillemets
     5  old="$IFS"
 
     6  #Modification de la valeur du IFS avec le "|"
     7  IFS="|"
 
     8  #Creation du tableau
     9  tab=( $chemin )
 
    10  #Restauration de la valeur du IFS
    11  #La variable $old doit être obligatoirement entre guillemets
    12  IFS="$old"
 
    13  #Parcourt du tableau
    14  for (( i=0 ; i<${#tab[*]} ; i++ )) ; do
    15          echo $i" -> "${tab[$i]}
    16  done
 
    17  exit 0
$

Résultat :

$ ./explode.sh
0 -> chemin 1
1 -> chemin 2 chemin 2 et demi
2 -> chemin 3
$

Afficher le détail des caractères d'une chaine de texte ou d'un fichier

Le script suivant permet d'afficher, par caractères, le nombre de fois qu'il est utilisé.

$ cat compteCaracteres.awk
BEGIN {
        RS = "\n"
}
 
{
        split($0, tab, "")
        for (var in tab) {
                tab2[tab[var]]+=1
        }
}
 
END {
        for (var in tab2) {
                printf "%1s --> %6d\n" ,  var , tab2[var]
        }
        exit 0
 
}

Exemple :

$ echo "ceci est un test" | awk -f compteCaracteres.awk
u -->      1
i -->      1
n -->      1
  -->      3
c -->      2
e -->      3
s -->      2
t -->      3

On peut également effectuer un tri sur le résultat :

$ echo "ceci est un test" | awk -f compteCaracteres.awk | sort
  -->      3
c -->      2
e -->      3
i -->      1
n -->      1
s -->      2
t -->      3
u -->      1

En utilisant un fichier en entrée :

$ cat file
TARGUANT
LOGOS
SOCRATISERONS
TEMPORISERENT
PLASTIQUAIENT
CORROBORER
BOTTELES
LIGOTA
SATINERONT
HYPNOTISERA

Affichage du résultat avec un tri décroissant sur le nombre de fois que le caractère est utilisé

$ cat file | awk -f compteCaracteres.awk | sort -b -n -k 3 -r
T -->     13
O -->     12
R -->     11
E -->     10
S -->      9
A -->      8
N -->      7
I -->      7
L -->      4
P -->      3
G -->      3
U -->      2
C -->      2
B -->      2
Y -->      1
Q -->      1
M -->      1
H -->      1

Etiquettes: 

Afficher toutes les interfaces réseau et leur adresse IP v4 correspondante

Voici un script qui permet d'afficher les adresses IP (v4) de toutes les interfaces réseau installées sur la machine.

Exécution :

./getInetAddr.sh 
eth0       ==>     10.33.43.10
lo         ==>       127.0.0.1
wlan0      ==>     172.22.8.35

Ce script est disponible en téléchargement ici .

Egalement disponible via GIT :

$ git clone http://git.quennec.fr/ronan/scripts_pub.git

Détail du script commenté :

#!/bin/bash
 
# Ce script retourne l'adresse IP
# de chaque interface réseau trouvée
 
# Pour le debuggage
#set -x
 
# Initialisation de la variable PATH
PATH="/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
 
# Nom du script
BASE=`basename $0`
# Le répertoire du script
DIR=`dirname $0`
 
# On boucle sur toutes les différentes interfaces trouvées
for I in `\
# On exécute la commande ifconfig
ifconfig | \
# On récupère le nom des différentes interfaces
# Le nom des interfaces se trouve dans la première
# colonne des informations retournées par la commande ifconfig
cut -d' ' -f1 | \
# On supprime toutes les lignes vides
sed -e '/^$/d'`; do
# On affecte à la variable J l'adresse IP correspondante
# à l'interface en cours de traitement par la boucle I
J=$(\
# On exécute la commande ifconfig pour l\'interface
# en cours de traitement par la boucle I
ifconfig $I | \
# On récupère la partie contenant l\'adresse IP
grep -E -o 'inet add?r:([0-9]{1,3}\.){3}[0-9]{1,3}' | \
# On concerve uniquement la partie IP
cut -d':' -f2 \
# On affiche le résultat
# sous la forme nomInterface ==> adresseIp
) && printf "%-10s ==> %15s\n" $I $J
done
 
# On quitte le script
exit 0
Etiquettes: 

Anagrammes

Voici un script qui permet de trouver les anagrammes d'un mot ou d'une suite de lettres.

Ce script utilise un dictionnaire de plus de 336500 mots.

Ce dictionnaire de mots peut être téléchargé ICI.

Il est également disponible ICI au format UTF-8.

Ce script s'utilise de cette manière :

anagramme.sh -f fichierDictionnaire [-d] -l nbLettre -c listeLettres

L'option -f permet d'indiquer le fichier "dictionnaire" à utiliser.

L'option -l permet d'indiquer le nombre de lettres des anagrammes à rechercher.

L'option -c permet d'indiquer le mot ou les lettres des anagrammes à rechercher.

L'option -d permet de ne pas prendre en compte les caractères accentués.

Cliquez ICI pour télécharger le script ou via mon GitLab.

Exécution du script :

# ./scripts/anagramme.sh -f liste.de.mots.francais.frgut.txt.utf8 -l 6 -c aspire
Liste des mots de 6 lettre(s) et contenant les lettres "aspire" :
1 - aspire
2 - paires
3 - paries
4 - parsie
5 - repais

# ./scripts/anagramme.sh -f liste.de.mots.francais.frgut.txt.utf8 -l 8 -c fuaaieujoslw
Liste des mots de 8 lettre(s) et contenant les lettres "fuaaieujoslw" :
1 - jalousai
2 - jalousie

Avec l'option -d :

# ./scripts/anagramme.sh -f liste.de.mots.francais.frgut.txt.utf8 -d -l 6 -c aspire
Liste des mots de 6 lettre(s) et contenant les lettres "aspire" :
1 - aspire
2 - aspire
3 - epairs
4 - paires
5 - paries
6 - paries
7 - parsie
8 - repais

Ci-dessous le détail du script avec un maximum de commentaires :

# nl scripts/anagramme.sh
     1  #!/bin/bash

     2  # Activation du debug
     3  # Décommenter pour activer
     4  #set -x

     5  # Fonction permettant de tester l'existence des commandes passées en argument
     6  function preRequis {
     7          for arg in $@; do
     8                  if ! which $arg >/dev/null; then
     9                          logger -t $0 "La commande $arg n'est pas installée"
    10                          echo "La commande $arg n'est pas installée !!!"
    11                          echo "Fin du script."
    12                          exit 1
    13                  fi
    14          done
    15  }

    16  # Journalisation de l'exécution du script
    17  logger -t $0 "Exécution du script"

    18  # Initialisation de la variable PATH
    19  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"

    20  # Exécution de la fonction preRequis
    21  preRequis grep sed awk

    22  # Vérification du nombre d'arguments passés au script
    23  #if [[ ! $# -eq 6 ]]; then
    24  if [[ $# -lt 6 || $# -gt 7 ]]; then
    25          echo "Nombre d'arguments incorrect"
    26          echo "Utilisation : $0 -f fichierDictionnaire [-d] -l nbLettre -c listeLettres"
    27          exit 1
    28  fi

    29  # Suppression des caractères accentués (0 = NON / 1 = OUI)
    30  supprAccents=0

    31  # Validation des arguments passés au script
    32  while getopts ":f:c:l:d" option; do
    33          case $option in
    34                  f)
    35                          if [ -f "$OPTARG" ]; then
    36                                  LISTE="$OPTARG"
    37                          else
    38                                  echo "L'option -f requiert un fichier existant."
    39                                  exit 1
    40                          fi
    41                          ;;
    42                  c)
    43                          listeDesLettres="$OPTARG"
    44                          if ! grep -E -q -i "^[a-z]*$" <<< "$listeDesLettres"; then
    45                                  echo "L'option -c requiert les lettres [a-z]."
    46                                  exit 1
    47                          fi
    48                          ;;
    49                  l)
    50                          nbLettre="$OPTARG"
    51                          if ! grep -E -q "^[0-9]*$" <<< "$nbLettre"; then
    52                                  echo "L'option -l requiert une valeur numérique."
    53                                  exit 1
    54                          fi
    55                          ;;
    56                  d)
    57                          supprAccents=1
    58                          ;;
    59                  :)
    60                          echo "L'option $OPTARG requiert un argument."
    61                          exit 1
    62                          ;;
    63                  \?)
    64                          echo "$OPTARG : option invalide."
    65                          exit 1
    66                          ;;
    67          esac
    68  done

    69  # Initialisation des variables utilisées pour le script
    70  listeDesLettres2="$listeDesLettres"
    71  listeDesMots2=""
    72  ind=1

    73  # Réécriture de la liste des lettres en incluant un pipe entre chaque lettre pour l'utiliser avec la commande grep
    74  # abcdef -> a|b|c|d|e|f|
    75  listeDesLettres=$(sed -r 's/([a-zA-Z])/\1\|/g' <<< "$listeDesLettres")

    76  # Recherche tous les mots contenant le nombre et les lettres indiqués
    77  if [[ $supprAccents = "0" ]]; then
    78          listeDesMots=$(cat "$LISTE" | grep -E -e "^.{$nbLettre}$" | grep -E -i "^[$listeDesLettres]+$")
    79  else
    80          listeDesMots=$(cat "$LISTE" | sed 'y/àâäéèêëîïôöùûüç/aaaeeeeiioouuuc/' | grep -E -e "^.{$nbLettre}$" | grep -E -i "^[$listeDesLettres]+$")
    81  fi

    82  # On parcourt tous les mots trouvés par la commande précédente.
    83  # Chaque mot et la liste des lettres sont passés à la commande AWK.
    84  # AWK initialise un tableau avec la liste des lettres (avec la commande split).
    85  # Chaque lettre est remplacée dans le mot par un blanc avec la commande sub ...
    86  # ... et le résultat renvoyé par la commande (1 en cas de succès et 0 en cas d'échec) ...
    87  # ... est multiplié à la variable "a". Pour finir, la commande AWK retourne le résultat de la variable "a".
    88  # Si la commande AWK retourne "1" (signifiant une erreur en BASH - D'où le "!" après le "if" )
    89  # c'est que toutes les lettres du mot correspondent à la liste des lettres à chercher.
    90  # On sauvegarde donc le mot en cours dans la variable "listeDesMots2".
    91  while read mot; do
    92  if ! echo "$mot|$listeDesLettres2" | awk -F'|' 'BEGIN{a=1;b=1}{split($1,tab,"");for(var in tab){b=sub(tab[var],"",$2);a*=b}}END{exit a}'; then
    93          listeDesMots2="$listeDesMots2\n$ind - $mot"
    94          ind=$(expr $ind + 1)
    95  fi
    96  done <<< "$listeDesMots"

    97  # Affichage de la liste des mots trouvés
    98  echo -n "Liste des mots de $nbLettre lettre(s) et contenant les lettres \"$listeDesLettres2\" :"
    99  echo -e "$listeDesMots2"

   100  # Journalisation de la fin du script
   101  logger -t $0 "Fin d'exécution du script"

   102  # Fin du script
   103  exit 0

 

Etiquettes: 

BASH : Parcourir tous les caractères d'une chaine

$ cat parcourtCaracteres
#!/usr/bin/env bash

STR="foobar"
for L in $(seq 1 ${#STR}); do
    echo $(echo $STR | cut -c$L)
done

 

La commande ${#STR} permet de connaitre la longueur de la chaine de caractères $STR.
Voir  pour plus d'explications.

Etiquettes: 

Calculer le PGCD et le PPCM d'une série de nombre

Voici un script qui permet de calculer le PGCD et le PPCM d'au moins deux nombres.

Il s'utilise de cette manière :

$ ./pgcd.sh 50 68 54 etc etc ...

Voici le contenu du script :

nl scripts/pgcd.sh

     1  #!/bin/bash
 
     2  # Ce script permet de calculer le PGCD et le PPCM
     3  # d'au moins deux nombres passés en argument.
     4  #
     5  # Il utilise quelques commandes intéressantes.
     6  # Elles sont toutes expliquées en détail sur www.quennec.fr
 
     7  # Fonction permettant de tester si les arguments
     8  # passés au script sont bien numériques et supérieur à 0
     9  function isNumeric() {
    10          for arg in $@; do
    11                  if ! expr "$arg" : '-\{0,1\}[0-9]\{1,\}$' >/dev/null; then
    12                          echo "ERREUR !!! $arg n'est pas un nombre."
    13                          exit 1
    14                  else
    15                          if expr "$arg" = 0 >/dev/null; then
    16                                  echo "ERREUR !!! Saisir un nombre superieur a 0"
    17                                  exit 1
    18                          fi
    19                  fi
    20          done
    21  }
 
    22  # On initialise la variable PATH
    23  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
 
    24  # On test si le nombre d'arguments passés
    25  # au script est bien supérieur ou égal à 2
    26  if [ $# -lt 2 ]; then
    27          echo "Usage: `basename $0` premier_nombre deuxieme-nombre etc etc ..."
    28          exit 1
    29  fi
 
    30  # On exécute la fonction isNumeric en lui passant en argument
    31  # tous les arguments passés au script
    32  isNumeric $@
 
    33  # Fonction permettant de calculer le PGCD
    34  # Cette fonction, je l'ai trouvé sur le site :
    36  function pgcd() {
    37          dividende=$1
    38          diviseur=$2
    39          reste=1
    40          until [ "$reste" -eq 0 ]; do
    41                  let "reste=$dividende%$diviseur"
    42                  dividende=$diviseur
    43                  diviseur=$reste
    44          done
    45  }
 
    46  NBR1=$1
    47  PPCM=$1
    48  VAR="($1"
 
    49  # On décale les arguments du scripts vers la gauche
    50  shift
 
    51  # On calcul le PPCM et le PGDC
    52  # de tous les nombres passés au script
    53  until [ "$#" -eq 0 ]; do
    54          NBR2=$1
    55          VAR="$VAR,$1"
    56          shift
    57          pgcd $PPCM $NBR2
    58          let "PPCM=$PPCM*$NBR2/$dividende"
    59          pgcd $NBR1 $NBR2
    60          NBR1=$dividende
    61  done
 
    62  VAR="$VAR)"
 
    63  # On affiche le résultat
    64  echo; echo "PGCD $VAR = $dividende"; echo
 
    65  echo "PPCM $VAR = $PPCM"; echo
 
    66  exit 0
 
Pour le télécharger, cliquer ici ou via mon GitLab.
Ou alors en ligne de commande :
$ wget -O pgcd.sh.tar http://www.isbeta.fr/83640

 

Chiffrer automatiquement un fichier avec mcrypt

Tous les détails de la commande mcrypt

La commande mcrypt propose différentes solutions afin de l'utiliser via un script.

Soit en utilisant un fichier de configuration, soit en utilisant des variables d'environnement.

Il est possible d'utiliser un fichier de configuration qui sera utilisé par défaut par la commande mcrypt.
Ce fichier doit être obligatoirement nommé ".mcryptrc" et placé dans le home de l'utilisateur.
Il devra contenir 3 paramètres :
- l'algorithme à utiliser
- le mode d'encryptage
- la phrase de passe

$ ls -l .mcryptrc
-rw------- 1 root root 46 31 oct.  09:09 .mcryptrc
$ cat .mcryptrc
algorithm des
mode cbc
key ma_phrase_de_passe
$

Lors de l'utilisation de la commande mcrypt, les paramètres d'encryptage seront automatiquement récupérés.

$ mcrypt monFichier
Warning: It is insecure to specify keywords in the command line
File monFichier was encrypted.
$ ls -l monFichier*
-rw-r--r-- 1 root root  0 31 oct.  08:32 monFichier
-rw------- 1 root root 84 31 oct.  08:32 monFichier.nc
$

Il est également possible d'utiliser un fichier de configuration nommé différemment mais dans ce cas, il faudra le spécifier lors de l'utilisation de la commande mcrypt avec l'option -c.

$ ls -l my_config_file
-rw------- 1 root root 46 31 oct.  09:15 my_config_file
$ cat my_config_file
algorithm des
mode cbc
key ma_phrase_de_passe
$ mcrypt -c my_config_file monFichier
Warning: It is insecure to specify keywords in the command line
File monFichier was encrypted.
$ ls -l monFichier*
-rw-r--r-- 1 root root  0 31 oct.  08:32 monFichier
-rw------- 1 root root 84 31 oct.  08:32 monFichier.nc
$

Il est possible égalment d'utiliser des variables d'environnement qu'il faudra initialiser et exporter directement dans le script utilisant la commande mcrypt.

Ces variables sont :

MCRYPT_KEY:la phrase de passe
MCRYPT_ALGO:l'algorithme à utiliser
MCRYPT_MODE:le mode d'encryptage

Exemple d'un script :

$ cat mon_script.sh
#!/bin/bash
 
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 
export MCRYPT_KEY="la phrase de passe"
export MCRYPT_ALGO="DES"
export MCRYPT_MODE="CBC"
 
if [[ -e monFichier.nc ]]; then
        rm monFichier.nc
fi
 
mcrypt monFichier
 
exit 0
$

Dans ce script, les variables propres à mcrypt sont initialisées et exportées.
Un test sur l'existence du fichier crypté permet de le supprimer avant d'exécuter la commande mcrypt (cela évite d'avoir un message de confirmation de la commande mcrypt pour écraser le fichier)
Enfin, la commande mcrypt est exécutée sur le fichier "monFichier".

Exécution du script :

$ ./mon_script.sh
File monFichier was encrypted.
$

Ce script peut être utilisé pour envoyer un fichier sur un serveur FTP par exemple sans compromettre les données du fichier.

Etiquettes: 

Convertion OGG to MP3

Pré-requis : Installer les paquets suivants

$ apt-get install ffmpeg
$ apt-get install ubuntu-restricted-extras
$ apt-get install lame


Exécuter le script suivant :

$ cat convert.sh
#!/bin/bash
for i in *.ogg
do
     j=${i%.ogg} ffmpeg -ab 192k -i "$j.ogg" "$j.mp3"
done  
exit 0

Convertit tous les fichiers présents dans le dossier où le script est exécuté

Etiquettes: 

Découper un mot en syllabes

Voici un script qui permet de découper un ou plusieurs mots en syllabes.

Merci à http://www.bertrandboutin.ca/Folder_151_Grammaire/P_b_division.htm pour la définition des syllabes.

Ce script peut être téléchargé ICI. ou via mon GitLab

Il s'utilise de cette manière :

$ ./syllabes.sh mot1 mot2 mot3 mot4 etc etc ...

Le script accepte au minimum un mot.

Voici le détail du script avec un maximum de commentaires :

$ cat syllabes.sh
#!/bin/bash

# Activer pour le debug
#set -x

function preRequis {
        for arg in $@; do
                if ! which $arg >/dev/null; then
                        echo "La commande $arg n'est pas installée !!!"
                        echo "Fin du script."
                        exit 1
                fi
        done
}

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"

preRequis egrep sed

# Si le nombre d'arguments passé au script est inférieur à 1
# On quitte le script immédiatement.
if [ $# -lt 1 ]; then
        echo "Usage: `basename $0` mot1 [mot2 mot3 ...]"
        exit 1
fi

# Liste des voyelles
VOY="aeiouyàâäéèêëîïôöùûü"
# Liste des consonnes
CONS="zrtpqsdfghjklmwxcvbnç"
# Liste des groupes de lettres insécables
GR="bl cl fl gl pl br cr dr fr gr pr tr vr ch ph gn th"

for MOT in $@; do

        # On convertit toutes les majuscules en minuscules
        _MOT=$(tr "[A-Z]" "[a-z]" <<< "$MOT")

        # On exécute la première règle de découpe des syllabes
        # avec les groupes de lettres insécables.
        for _GR in $(echo $GR); do
                _MOT=$(sed "s/$_GR/-$_GR/g" <<< "$_MOT")
        done

        # Boucle infinie
        while :; do

                # Une consonne placée entre deux voyelles introduit une nouvelle syllabe.
                if SYL=$(grep -E -o "[$VOY]{1}[$CONS]{1}[$VOY]{1}" <<< "$_MOT"); then
                        for __SYL in $SYL; do
                                _SYL=$(sed -r "s/^(.)(.{2})$/\1-\2/" <<< "$__SYL")
                                _MOT=$(sed "s/$__SYL/$_SYL/" <<< "$_MOT")
                        done
                        continue
                fi

                # Deux consonnes placées entre deux voyelles,
                # la première appartient à la syllabe précédente,
                # la seconde, à la syllabe suivante.
                if SYL=$(grep -E -o "[$VOY]{1}[$CONS]{2}[$VOY]{1}" <<< "$_MOT"); then
                        for __SYL in $SYL; do
                                _SYL=$(sed -r "s/^(.{2})(.{2})$/\1-\2/" <<< "$__SYL")
                                _MOT=$(sed "s/$__SYL/$_SYL/" <<< "$_MOT")
                        done
                        continue
                fi

                # Quand il y a trois consonnes ou voyelles consécutives à l’intérieur d’un mot,
                # ordinairement les deux premières terminent une syllabe,
                # l’autre commence une nouvelle syllabe.
                if SYL=$(grep -E -o "[$CONS]{3}|[$VOY]{3}" <<< "$_MOT"); then
                        for __SYL in $SYL; do
                                _SYL=$(sed -r "s/^(.{2})(.)$/\1-\2/" <<< "$__SYL")
                                _MOT=$(sed "s/$__SYL/$_SYL/" <<< "$_MOT")
                        done
                        continue
                fi

                # On quitte la boucle infinie si aucune des conditions précédentes n'est vraie
                break

        done

        # On affiche le résultat
        _MOT=$(sed "s/^-//" <<< "$_MOT")
        echo -e "$MOT => $_MOT"

done

exit 0

Enregistrer les erreurs d'exécution d'une commande ou d'un script dans un fichier log avec horodatage

Enregistrer les erreurs d'exécution d'une commande ou d'un script dans un fichier de log peut se faire tout simplement en redirigeant la sortie d'erreur standard (descripteur #2) vers un fichier :

$ cp fichierA fichierB 2>>/var/log/cp_error.log

Petit rappel :
2>/mon_fichier : Tout le contenu du fichier est écrasé
2>>/mon_fichier : Les données sont ajoutées à la fin du fichier

La consultation du fichier log :

$ cat /var/log/cp_error.log
cp: impossible d'évaluer « fichierA »: Aucun fichier ou dossier de ce type
$

C'est clair et précis. L'erreur rencontrée par la commande cp a bien été enregistrée dans le fichier.
Mais la précision pourrait être un peu plus détaillée surtout si cela concerne une commande ou un script exécuté régulièrement par une tâche cron.

Le but, obtenir un fichier de log avec la date et l'heure de l'erreur rencontrée :

$ cat /var/log/cp_error.log
ven. 24 août 2012 15:10:01 CEST --- cp: impossible d'évaluer « fichierA »: Aucun fichier ou dossier de ce type
ven. 24 août 2012 15:12:07 CEST --- cp: impossible d'évaluer « fichier1 »: Aucun fichier ou dossier de ce type
ven. 24 août 2012 15:12:07 CEST --- cp: impossible d'évaluer « fichier2 »: Aucun fichier ou dossier de ce type
ven. 24 août 2012 15:12:07 CEST --- cp: impossible d'évaluer « fichier3 »: Aucun fichier ou dossier de ce type
ven. 24 août 2012 15:12:07 CEST --- cp: impossible d'évaluer « fichier4 »: Aucun fichier ou dossier de ce type
ven. 24 août 2012 15:12:07 CEST --- cp: impossible d'évaluer « fichier5 »: Aucun fichier ou dossier de ce type
ven. 24 août 2012 15:12:07 CEST --- cp: impossible d'évaluer « fichier6 »: Aucun fichier ou dossier de ce type
ven. 24 août 2012 15:12:07 CEST --- cp: impossible d'évaluer « fichier7 »: Aucun fichier ou dossier de ce type
ven. 24 août 2012 15:12:07 CEST --- cp: impossible d'évaluer « fichier8 »: Aucun fichier ou dossier de ce type
ven. 24 août 2012 15:12:07 CEST --- cp: impossible d'évaluer « fichier9 »: Aucun fichier ou dossier de ce type
ven. 24 août 2012 15:12:07 CEST --- cp: impossible d'évaluer « fichier10 »: Aucun fichier ou dossier de ce type
$

C'est quand même mieux de connaitre la date et l'heure de l'erreur rencontrée.

La manière de le faire ? Avec un simple script awk.

Pré-requis :

Avoir gawk installé sur la machine.

$ dpkg -l | grep -i awk
ii  gawk                                                   1:3.1.7.dfsg-5               GNU awk, a pattern scanning and processing language
ii  mawk                                                   1.3.3-15                     a pattern scanning and text processing language
$

S'il n'est pas installé :

$ apt-get install gawk

Détail du script awk :

$ cat log.awk
{
        date_heure=strftime("%c",systime())
        printf ("%s --- %s\n", date_heure, $0)
}
 
END {
     exit 0
}
$

Que fait-il :

Ce script reçoit une donnée en entrée récupérée grâce à la variable $0, initialise une variable date_heure avec la date et l'heure courante grâce à la commande systime() et formatée grâce à la commande strftime puis envoi le tout sur sa sortie standard grâce à la fonction printf.

Comment l'utiliser :

Avec une commande shell :

$ cp fichierA fichierB 2>&1 >&- | /usr/bin/awk -f /root/log.awk >> /var/log/cp_error.log

La commande cp tente de copier le fichierA vers le fichierB.
La sortie d'erreur standard de la commande cp est renvoyée en premier vers la sortie standard.
La sortie standard est ensuite fermée ce qui fait que seules les erreurs sont envoyées sur la sortie standard de la commande.
La sortie standard de la commande cp est ensuite envoyée au script log.awk.
Enfin, la sortie standard du script log.awk est envoyée vers le fichier de log souhaité.

L'utilisation avec un script est aussi possible :

$ /root/mon_script.sh 2>&1 >&- | /usr/bin/awk -f /root/log.awk >> /var/log/mon_fichier.log

Si l'on souhaite envoyer la totalité des résultats d'une commande ou d'un script dans le fichier de log, il suffit de supprimer la fermeture du descripteur #1.

$ cp fichierA fichierB 2>&1 | /usr/bin/awk -f /root/log.awk >> /var/log/cp_error.log

Etiquettes: 

Rechercher les doublons d'un ou plusieurs fichiers

Il n'est pas rare d'avoir sur son disque dur le même fichier présent à plusieurs endroits.

Comme des photos, par exemple ou des programmes.

Que de place perdue pour pas grand chose.

Voici un petit script qui scrute le répertoire, passé en argument, à la recherche de fichiers en double (voir plus).

Comme dans la plupart de mes scripts, vous y retrouverez la fonction "preRequis" permettant de savoir si toutes les commandes utilisées dans le script sont biens installées sur le système et la commande logger permettant de journaliser l'exécution du script dans /var/log/syslog.

Téléchargé le script ici.

Le script s'utilise de cette manière :

$ ./rechercheDoublons.sh mon_repertoire

J'utilise la commande find avec l'option -type f qui permet de rechercher tous les fichiers réguliers dans le répertoire passé en argument.
Pour chaque fichier retourné par la commande find, la commande md5sum lit le fichier en mode binaire (avec l'option -b) et écrit l'empreinte md5 du fichier dans le fichier /tmp/filesMd5sum.
Pour finir, le contenu du fichier /tmp/filesMd5sum est trié avec la commande sort, et tous les fichiers ayant la même empreinte md5 (grâce aux commandes awk '{print $1}' | uniq -d) sont affichés à l'écran.

# cat rechercheDoublons.sh
#!/bin/bash

function preRequis {
        for arg in $@; do
                if ! which $arg >/dev/null; then
                        logger -t $0 La commande $arg n\'est pas installée
                        echo "La commande $arg n'est pas installée !!!"
                        echo "Fin du script."
                        exit 1
                fi
        done
}

logger -t $0 Exécution du script

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"

preRequis md5sum sort awk uniq grep cut find

if [ ! $# -eq 1 ]; then
        echo "Erreur !!!"
        echo "Utilisation : $0 répertoire"
        exit 1
fi

FILE="/tmp/filesMd5sum"
REP="$1"

if [ ! -d "$REP" ]; then
        echo "Erreur !!!"
        echo "$REP n'est pas un répertoire."
        exit 1
fi

rm -f "$FILE"

find "$REP" -type f -exec md5sum -b {} \; > "$FILE"

DOUBLON=0

for file in $(cat "$FILE" | sort | awk '{print $1}' | uniq -d); do
        DOUBLON=1
        echo "Empreinte MD5 identique : $file"
        grep $file "$FILE" | cut -d' ' -f2
done

if [ "$DOUBLON" -eq 0 ]; then echo "Aucun doublon trouvé"; fi

logger -t $0 Fin d\'exécution du script

exit 0

 

Script d'archivage incrémental et transfert sftp automatique

CPIO

Pré-requis pour que le script suivant fonctionne :

1 - Paramétrer sur le poste à sauvegarder un accès ssh au serveur de sauvegarde via un système d'authentification par clé privée / publique.

Tout est expliqué ici : http://quennec.fr/linux/utilisation/connexion-a-une-machine-distante-sans-saisir-le-mot-de-passe

2 - Le programme bzip2 doit être installé sur le poste à sauvegarder.

$ apt-get install bzip2

3 - Rendre les scripts exécutables

$ chmod +x uploadBackup.sh && chmod +x fonctions.inc.sh

Script d'archivage incrémental et transfert sftp automatique

Ce script permet d'effectuer une sauvegarde incrémentale d'un répertoire vers un serveur de sauvegarde.
Il utilise un système de niveau correspondant au jour du mois - 1.
Tous les 1er de chaque mois, une sauvegarde totale (niveau 0) est effectuée.
Une sauvegarde incrémentale est effectuée les jours suivants.

Le script est composé de 2 fichiers.
Un fichier comportant le script principal (uploadBackup.sh) et un fichier comportant les fonctions personnalisées utiles au script principal (fonctions.inc.sh).

Les fichiers à sauvegarder (variable DATADIR) sont enregistrés dans une archive CPIO compressée avec BZIP2 et stockée dans un répertoire local sur le poste à sauvegarder (variable ARCHIVEDIR).
Avant chaque sauvegarde, un fichier de niveau est créé dans le répertoire local.
Toutes les logs sont enregistrées dans un fichier stocké également dans le répertoire local.
La sauvegarde incrémentale utilise le fichier niveau précédent afin de sauvegarder tous les fichiers modifiés depuis la sauvegarde précédente grâce à la commande find et l'option -newer.
Enfin, l'archive CPIO est envoyée sur le serveur de sauvegarde (variable serveur_sauvegarde) via SFTP et stockée dans des sous-répertoires correspondant à l'année et au mois de la sauvegarde dans le dossier de sauvegarde (variable dossier_distant) .

Détail du fichier uploadBackup.sh

$ nl uploadBackup.sh
     1  #!/bin/bash
     2  # set -x
     3  # Répertoire des scripts shell
     4  SCRIPTDIR="/root/script_archivage_incremental"
     5  # Répertoire des fichiers à sauvegarder
     6  DATADIR="/root/dossier_a_sauvegarder"
     7  # Répertoire local des archives
     8  ARCHIVEDIR="/root/local_backup"
     9  # Inclure les fonctions
    10  . $SCRIPTDIR/fonctions.inc.sh
    11  # Fichier de log
    12  LOG=$ARCHIVEDIR/`getDate`.log
    13  # Redirection de toutes les sorties du script vers le fichier de log
    14  exec 1>$LOG 2>&1
    15  # Déterminer le niveau de sauvegarde
    16  # Le 1er du mois => niveau 0
    17  jourDuMois=`getDayForCalcul`
    18  ((niveau=$jourDuMois-1))
    19  case $niveau in
    20          0) # Sauvegarde totale
    21                  # Nettoyage du répertoire d'archive
    22                  rm -i $ARCHIVEDIR/*.bz2 $ARCHIVEDIR/niveau*
    23                  # Création du fichier de niveau (niveau 0)
    24                  touch $ARCHIVEDIR/niveau0
    25                  archive="$ARCHIVEDIR/`getDate`_niveau0.cpio"
    26                  find $DATADIR | cpio -ocv | bzip2 -c > $archive.bz2
    27                  ;;
    28          *)
    29                  # Creation du fichier de niveau
    30                  touch $ARCHIVEDIR/niveau$niveau
    31                  archive="$ARCHIVEDIR/`getDate`_niveau${niveau}.cpio"
    32                  # Determination du niveau precedent
    33                  ((niveauPrec=$niveau-1))
    34                  # Test si le fichier de niveau precedent existe
    35                  if [[ ! -f $ARCHIVEDIR/niveau$niveauPrec ]]
    36                  then
    37                          # Si il n'existe pas, sauvegarde integrale du repertoire
    38                          echo "Fichier de niveau $niveauPrec inexistant"
    39                          echo "Execution d'une sauvegarde integrale en cours de mois"
    40                          find $DATADIR | cpio -ocv | bzip2 -c > $archive.bz2
    41                  else
    42                          # Sauvegarde incrementale
    43                          find $DATADIR -newer $ARCHIVEDIR/niveau$niveauPrec | cpio -ocv | bzip2 -c > $archive.bz2
    44                  fi
    45                  ;;
    46  esac
    47  # Vérification de la validité de l'archive
    48  if isArchiveInvalide $archive.bz2 ; then
    49          echo "Archive $archive.bz2 INVALIDE - Fichier non transfere"
    50          exit 1
    51  fi
    52  # Transfert du fichier vers le serveur de sauvegarde
    53  if transfert ${archive}.bz2 ; then
    54          echo "Transfert realise avec succes"
    55          exit 0
    56  fi
    57  # Si le transfert a echoue
    58  echo "Echec de transfert"
    59  exit 1
$

Détail du fichier fonctions.inc.sh

$ nl fonctions.inc.sh
     1  #!/bin/bash
     2  function transfert {
     3          typeset mois
     4          typeset annee
     5          # Recuperation de la valeur du premier argument passe a la fonction
     6          # Recuperation du nom de l'archive a envoyer au serveur de sauvegarde
     7          typeset ficATransferer=$1
     8          # Adresse du serveur de sauvegarde
     9          typeset serveur_sauvegarde="192.168.1.113"
    10          # Compte utilise pour se connecter au serveur de sauvegarde
    11          typeset user="root"
    12          # Chemin absolu du dossier ou sera stocke la sauvegarde
    13          typeset dossier_distant="/root/sauvegarde_dossier"
    14          mois=`getMonth`
    15          annee=`getYear`
    16          # Test si le dossier de sauvegarde existe sur le serveur de sauvegarde
    17          # Connexion au serveur avec le user root
    18          ssh $user@$serveur_sauvegarde test -d $dossier_distant/$annee/$mois
    19          # Test sur le code retour de la commande precedente
    20          case $? in
    21                  0)
    22                          ;;
    23                  255)
    24                          echo "Echec de la commande SSH"
    25                          return 1
    26                          ;;
    27                  *)
    28                          # Si code retour different de 0 et 255
    29                          # Creation du repertoire de la sauvegarde
    30                          ssh $user@$serveur_sauvegarde mkdir -p $dossier_distant/$annee/$mois
    31                          ;;
    32          esac
    33          # Connexion au serveur de sauvegarde en FTP sécurisé
    34          # Ne pas oublier les doubles chevrons << avant le mot cle FIN
    35          # Ne pas mettre d'espace entre << et FIN
    36          sftp -b - $user@$serveur_sauvegarde <<FIN
    37          # Positionnement dans le repertoire de la sauvegarde
    38          cd $dossier_distant/$annee/$mois
    39          pwd
    40          # Envoi de la sauvegarde
    41          put $ficATransferer
    42  FIN
    43  # Ne pas mettre de tabulation ou d'espace devant le mot clé FIN
    44  # Sinon celui-ci n'est pas reconnu
    45          # Test sur le code retour de la commande SFTP
    46          # Si le code retour est different de 0
    47          # Une anomalie a ete rencontree
    48          (( $? != 0 )) && return 1
    49          # Tester si archive valide sur serveur de sauvegarde
    50          ficSurMachineCible=$(basename $ficATransferer)
    51          ssh $user@$serveur_sauvegarde bzip2 -t $dossier_distant/$annee/$mois/$ficSurMachineCible
    52          case $? in
    53                  0)
    54                          ;;
    55                  255)
    56                          echo "Echec de la commande SSH"
    57                          return 1
    58                          ;;
    59                  *)
    60                          # Si code retour different de 0 et 255
    61                          # Alors l'archive est invalide
    62                          echo "Archive $dossier_distant/$annee/$mois/$ficSurMachineCible INVALIDE"
    63                          return 1
    64                          ;;
    65          esac
    66          return 0
    67  }
    68  function isArchiveInvalide {
    69          typeset archive=$1
    70          bzip2 -t $archive 2>/dev/null && return 1
    71          return 0
    72  }
    73  function getDate {
    74          date '+%Y_%m_%d'
    75  }
    76  function getYear {
    77          date '+%Y'
    78  }
    79  function getMonth {
    80          date '+%m'
    81  }
    82  function getDayForCalcul {
    83          date '+%e' | sed 's/ //'
    84  }
$

Une fonction permettant de vérifier si les commandes utilisées dans le script sont installées sur le système

Quand on développe des scripts pour soi-même, toutes les commandes utilisées dans le script sont obligatoirement installées sur le système. Mais qu'en est-il si le script est partagé avec différentes personnes sur différents sytèmes ?

Il faut être sûr et certain que le script sera utilisable n'importe où et par n'importe qui.

C'est pour cette raison que j'utilise de plus en plus cette fonction dans mes scripts.

function preRequis {
        for arg in $@; do
                if ! which $arg >/dev/null; then
                        echo "La commande $arg n'est pas installée !!!"
                        echo "Fin du script."
                        exit 1
                fi
        done
}

Cette fonction, je l'ai appelé "preRequis". Elle reçoit des noms de commandes en arguments et vérifie à l'aide de la commande which (commande primitive du shell) l'existence sur le système de ces commandes.

Grâce à cette fonction, si une personne exécute un script contenant une commande qui n'est pas installée sur son système, un message explicite sera affiché à l'écran.

Cette fonction peut être intégrée dans n'importe quel script.

$ cat sauvegarde_differentielle.sh
#!/bin/bash
function preRequis {
        for arg in $@; do
                if ! which $arg >/dev/null; then
                        echo "La commande $arg n'est pas installée !!!"
                        echo "Fin du script."
                        exit 1
                fi
        done
}

preRequis nice rdiff-backup
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
exec 1>>/var/log/sauvegarde_differentielle.log
exec 2>>/var/log/sauvegarde_differentielle_error.log
nice -n 19 rdiff-backup /repertoire_a_sauvegarder /destination_de_la_sauvegarde && nice -n 19 rdiff-backup --remove-older-than 1W --force /destination_de_la_sauvegarde
exit 0
$

Dans cet exemple, j'utilise la fonction preRequis pour vérifier que les commandes nice et rdiff-backup sont bien installées sur le système.

Vérifier régulièrement le contenu d'une page web et recevoir un avertissement par mail

Voici un script qui se charge de vérifier les différences qu'il peut y avoir sur une page web entre 2 périodes de temps définies.

$ nl check_url.sh
     1  #!/bin/bash
 
     2  export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
     3  URL="http://quennec.fr"
     4  PREC="/root/precedent"
     5  SUIV="/root/suivant"
 
     6  exec 1>/dev/null 2>&1
 
     7  if [ -e $SUIV ]; then
     8          rm $SUIV
     9  fi
 
    10  curl $URL > $SUIV
 
    11  if [ -e $PREC ]; then
 
    12          diff $SUIV $PREC
    13          if [ $? == 1 ]; then
    14                  mail -s "Ecart sur la page $URL" ronan@quennec.fr<<EOF
    15  EOF
    16          fi
 
    17  fi
 
    18  if [ -e $PREC ]; then
    19          rm $PREC
    20  fi
 
    21  mv $SUIV $PREC
 
    22  exit 0
$

Lignes 2 à 5 : initialisation des variables utilisées dans le script.
Ligne 6 : Redirection des entrées et sorties standards.
Ligne 7 à 9 : Suppression du fichier $SUIV si celui-ci existe.
Ligne 10 : Téléchargement du contenu de la page web et enregistrement dans le fichier $SUIV
Ligne 11 à 17 : Si le fichier $PREC existe, le programme diff compare les 2 fichiers $SUIV et $PREC. Si il y a des différences ($? == 1), un mail est envoyé à l'adresse indiquée.
Ligne 18 à 20 : Si le fichier $PREC existe, il est supprimé.
Ligne 21 : Le fichier $SUIV est renommé en $PREC.

Rendre le script exécutable :

$ chmod +x check_url.sh

Reste à exécuter le script

$ ./check_url.sh

Pour l'automatisation, une ligne sera ajoutée à crontab :

$ crontab -e
*/5     *       *       *       *       /root/check_url.sh

Le script sera exécuté toutes les 5 minutes.

Fichier attachéTaille
Plain text icon check_url.sh_.txt460 octets
Etiquettes: