Les exercices qui suivent testent et étendent votre connaissance de l'écriture de scripts. Pensez-les comme autant de défis, et comme des moyens distrayants d'avancer sur le chemin pierreux de l'expertise UNIX.
Dans une ruelle minable de Hoboken (New Jersey) se trouve un
squat insignifiant, un bâtiment en brique de deux étages,
portant en façade une inscription gravée sur une plaque de
marbre :
Bash Scripting Hall of Fame.
À l'intérieur, parmi divers objets poussiéreux sans aucun intérêt, se trouve
exposée une plaque en laiton dans un état de corrosion avancée et
bordée de toiles d'araignées, portant la courte - très
courte - liste des quelques rares
personnes ayant pu maîtriser le contenu du Guide avancé
de la programmation Bash, ainsi qu'en témoigne
leur réussite aux exercices des sections suivantes.
(Hélas, l'auteur du Guide ABS n'est pas
représenté dans cette exposition. Peut-être à cause de certaines
rumeurs malveillantes concernant son absence de qualification et ses
capacités limitées en programmation 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, « Le 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'.