M. Exercices

Les exercices qui suivent testent et étendent votre connaissance de l'écriture de scripts. Pensez-y comme à autant de challenges, comme à un moyen de vous amuser pour aller plus loin sur le chemin de l'expertise UNIX.

Sur une petite rue de Hoboken, New Jersey, se trouve un squat difficilement descriptible dans un bâtiment en brique de deux étages et contenant sur sa façade une inscription gravée sur une plaque de marbre : Bash Scripting Hall of Fame. À l'intérieur, entre différents tableaux poussiéreux exposés, se trouve une plaque en laiton avec une courte, très courte liste de ces rares personnes qui ont réussi à maîtriser le contenu du Guide sur l'écriture avancée de scripts Bash, comme en témoigne leur réussite aux exercices suivants...

M.1. Analyse de scripts

Examinez le script suivant. Lancez-le, puis expliquez ce qu'il fait. Annotez le script, puis ré-écrivez-le d'une façon plus compacte et plus élégante.

#!/bin/bash

MAX=10000


  for((nr=1; nr<$MAX; nr++))
  do

    let "t1 = nr % 5"
    if [ "$t1" -ne 3 ]
    then
      continue
    fi

    let "t2 = nr % 7"
    if [ "$t2" -ne 4 ]
    then
      continue
    fi

    let "t3 = nr % 9"
    if [ "$t3" -ne 5 ]
    then
      continue
    fi

  break   # Que se passe-t-il quand vous mettez cette ligne en commentaire ?
          # Pourquoi ?

  done

  echo "Nombre = $nr"


exit 0

---

Expliquez ce que fait le script suivant. C'est réellement seulement un tube paramétré en ligne de commande.

#!/bin/bash

REPERTOIRE=/usr/bin
TYPEFICHIER="shell script"
JOURNAL=logfile

file "$REPERTOIRE"/* | fgrep "$TYPEFICHIER" | tee $JOURNAL | wc -l

exit 0

---

Examinez et expliquez le script suivant. Pour vous aider : find et stat.

#!/bin/bash

# Auteur :  Nathan Coulter
# Ce code est dans le domaine public.
# L'auteur a donné sa permission d'utiliser ce code dans le guide ABS.

find -maxdepth 1 -type f -printf '%f\000'  | {
   while read -d $'\000'; do
      mv "$REPLY" "$(date -d "$(stat -c '%y' "$REPLY") " '+%Y%m%d%H%M%S'
      )-$REPLY"
   done
}

# Attention : testez ce script dans un répertoire de tests.
# Car il touche aux fichiers qui en font partie.

---

Un lecteur a envoyé le code suivant.

while read LIGNE
do
  echo $LIGNE
done < `tail -f /var/log/messages`

Il souhaitait écrire un script traçant les modifications dans le journal système, /var/log/messages. Malheureusement, le bloc de code ci-dessus se bloque et ne fait rien d'utile. Pourquoi ? Corrigez-le pour qu'il fonctionne (indice : plutôt que de rediriger l'entrée standard stdin de la boucle, essayez un tube).

---

Analyser le « code sur une ligne » (ici séparé sur deux lignes pour plus de clareté) contribué par Rory Winston :

export SUM=0; for f in $(find src -name "*.java");
do export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }'))); done; echo $SUM

Astuce : tout d'abord, diviser le script en petites sections. Puis, examinez avec attention son utilisation de l'arithmétique par parenthèses doubles, et des commandes export, find, wc et awk.

---

Analyser l'Exemple A.10, « « life : Jeu de la Vie » » et ré-organisez-le en suivant un style simplifié et plus logique. Cherchez combien de ses variables peuvent être éliminées et essayez d'optimiser le temps d'exécution du script.

Modifiez le script pour qu'il accepte n'importe quel fichier texte ASCII pour sa « génération » initiale. Le script lira les $ROW*$COL premiers caractères et initialisera les occurences de voyelles comme des cellules « vivantes ». Indice : assurez-vous de remplacer les espaces dans le fichier d'entrée par des caractères 'tiret bas'.