Atelier BASH du vendredi 20 mars 2015 par PhilippeLhardy
BASH = Bourne Again SHell
Des lectures à conseiller :
Voir aussi cette page du blog de Philippe et nos archives de liste de diffusion:
BASH = Bourne Again SHell
Des lectures à conseiller :
- http://fr.wikipedia.org/wiki/Shebang
- http://fr.wikipedia.org/wiki/Flux_standard
- http://abs.traduc.org/abs-5.1-fr/ch17.html
- http://abs.traduc.org/abs-5.3-fr/ch14.html
- http://pwet.fr/man/linux/commandes/bash
- http://www.tuteurs.ens.fr/unix/shell/entreesortie.html
- http://www.gnu.org/software/bash/
- http://www.trustonme.net/didactels/148.html
- http://aadelmar.free.fr/bash_exemple.html
- http://www.cyberciti.biz/tips/linux-write-sys-v-init-script-to-start-stop-service.html
- http://www.cas.mcmaster.ca/~nedialk/COURSES/3f03/pdf/bash.quickref.pdf
Voir aussi cette page du blog de Philippe et nos archives de liste de diffusion:
- http://blog.artisanlogiciel.net/post/2015/03/21/Atelier-Bash-%C3%A0-Linux-Azur
- https://lists.linux-azur.org/pipermail/linux06/2015-March/000746.html
- scriptdephilippe.sh
- chmod u+rx scriptdephilippe.sh
- ./scriptdephilippe.sh
#!/bin/bash # la ligne qui précède s'appelle le shebang # cette ligne ainsi que la précédente et la suivante sont des lignes de commentaires # en revanche la ligne suivante n'est pas un commentaire echo "Creation d'un tableau à l'aide d'une boucle for" echo "on créé un tableau qui contient une table de 5 éléments (5 trucs) indexés" echo "depuis la position 0 jusqu'à la position 4." declare -a tableau for (( i=0 ; $i < 5 ; i++ )) # oui les doubles parenthèses sont obligatoires do index=$(( i + 1 )) # oui la aussi les doubles parenthèses sont obligatoires echo "Tapez un truc pour voir... ($index)" read UNTRUC echo "$index) $UNTRUC" tableau[$i]=$UNTRUC done taille_tableau=${#tableau[@]} for (( i=0 ; $i < $taille_tableau ; i++ )) do echo "$(( i + 1 )): ${tableau[$i]}" done echo "Ex1 : transformez moi pour ne demander que 3 valeurs a lieu de 5." # la réponse : il faut mettre 3 au lieu de 5 ici : for (( i=0 ; $i < 3 ; i++ )) do index=$(( i + 1 )) echo "Tapez un truc pour voir... ($index)" read UNTRUC echo "$index) $UNTRUC" if [[ $UNTRUC == "la solution est la ..." ]] then break else tableau[$i]=$UNTRUC fi done taille_tableau=${#tableau[@]} for (( i=0 ; $i < $taille_tableau ; i++ )) do contenu=${tableau[$i]} echo "$(( i + 1 )): $contenu" if [[ "$toobad" == "stop" ]] then echo "Curieux, on aurait du s'arreter avant ..." >&2 elif [[ "$contenu" == "STOP" ]] then echo "Curieux, on aurait du ne pas enregistrer cette valeur ..." >&2 toobad=stop fi done echo "Transformez moi pour s'arreter de demander d'autres trucs si la réponse est 'STOP' et demander jusqu'à 20 trucs maximum." echo "Mais pourquoi y a t'il des >&2 pour les Curieux ???" echo "Qu'est ce qui va nous arreter ?" read ARRET # on créé un tableau qui contient une table d'élément indexé par position partant de 0. declare -a tableau # 20 max : il faut mettre 20 au lieu de 3 ici : for (( i=0 ; $i < 20 ; i++ )) do index=$(( i + 1 )) echo "Tapez un truc pour voir... ($index)" read UNTRUC echo "$index) $UNTRUC" # etape 5 : il faut tester si UNTRUC vaut STOP ... if [[ $UNTRUC == "STOP" ]] then break else tableau[$i]=$UNTRUC fi done taille_tableau=${#tableau[@]} for (( i=0 ; $i < $taille_tableau ; i++ )) do contenu=${tableau[$i]} echo "$(( i + 1 )): $contenu" if [[ "$toobad" == "stop" ]] then # les >&2 c'est pour écrire sur la sortie d'erreur et non sur la sortie standard. echo "Curieux, on aurait du s'arreter avant ..." >&2 elif [[ "$contenu" == "$ARRET" ]] then echo "Curieux, on aurait du ne pas enregistrer cette valeur puisque c'est la valeur d'arret..." >&2 toobad=stop fi done echo "Transformez moi pour s'arreter de demander d'autres trucs si la réponse est la même que la condition ARRET demandée au début." echo "Qu'est ce qui va nous arreter ?" read ARRET # on créé un tableau qui contient une table d'élément indexé par position partant de 0. declare -a tableau for (( i=0 ; $i < 20 ; i++ )) do index=$(( i + 1 )) echo "Tapez un truc pour voir... ($index)" read UNTRUC echo "$index) $UNTRUC" # etape 6 : il faut tester si UNTRUC vaut le contenu de ARRET : if [[ $UNTRUC == "$ARRET" ]] then break else tableau[$i]=$UNTRUC fi done taille_tableau=${#tableau[@]} mon_fichier="oh_fichier" echo "Oh le beau tableau qui va suivre" >$mon_fichier for (( i=0 ; $i < $taille_tableau ; i++ )) do contenu=${tableau[$i]} echo "$(( i + 1 )): $contenu" $mon_fichier echo "$(( i + 1 )): $contenu" >>$mon_fichier if [[ "$toobad" == "stop" ]] then # les >&2 c'est pour écrire sur la sortie d'erreur et non sur la sortie standard. echo "Curieux, on aurait du s'arreter avant ..." >&2 elif [[ "$contenu" == "$ARRET" ]] then echo "Curieux, on aurait du ne pas enregistrer cette valeur puisque c'est la valeur d'arret..." >&2 toobad=stop fi done echo "Voici ce que contient $mon_fichier:" cat $mon_fichier echo echo "Transformez moi pour sauvegarder le résultat dans un fichier nommé le_beau_fichier.txt" echo "Tiens au passage pourquoi on utilise >$mon_fichier au début puis >>$mon_fichier dans la boucle ? Qu'est-ce qu'il se passe sinon" # on a regroupé en fonction un ensemble d'actions en relation echo "Des fonctions ..." # on créé un tableau qui contient une table d'élément indexé par position partant de 0. declare -a tableau # on va pas dire que c'etait très compliqué ... mon_fichier="le_beau_fichier.txt" saisie() { echo "C'est quoi qui va nous arreter ?" read ARRET taille_tableau=${#tableau[@]} for (( i=$taille_tableau ; $i < 20 ; i++ )) do index=$(( i + 1 )) echo "Tapez un truc pour voir... ($index)" read UNTRUC echo "$index) $UNTRUC" # etape 6 : il faut tester si UNTRUC vaut le contenu de ARRET : if [[ $UNTRUC == "$ARRET" ]] then break else tableau[$i]=$UNTRUC fi done } sauvegarde() { taille_tableau=${#tableau[@]} # >$mon_fichier créé un nouveau fichier echo "Oh le beau tableau qui va suivre" >$mon_fichier for (( i=0 ; $i < $taille_tableau ; i++ )) do contenu=${tableau[$i]} echo "$(( i + 1 )): $contenu" # >>$mon_fichier ( notez les deux > ) ajoute à la fin du fichier existant echo "$(( i + 1 )): $contenu" >>$mon_fichier if [[ "$toobad" == "stop" ]] then # les >&2 c'est pour écrire sur la sortie d'erreur et non sur la sortie standard. echo "Curieux, on aurait du s'arreter avant ..." >&2 elif [[ "$contenu" == "$ARRET" ]] then echo "Curieux, on aurait du ne pas enregistrer cette valeur puisque c'est la valeur d'arret..." >&2 toobad=stop fi done } lecture() { while read INDEX_UNTRUC do if [[ $INDEX_UNTRUC =~ [0-9]*:\ (.*) ]] then UNTRUC=${BASH_REMATCH[1]} tableau[${#tableau[@]}]=$UNTRUC fi done < $mon_fichier } # vraiment cette solution c'est sans commentaire ! # lecture saisie sauvegarde echo "Voici ce que contient $mon_fichier:" cat $mon_fichier echo "Transformez moi pour lire la liste précédente depuis le_beau_fichier.txt avant la saisie" echo "A quoi peut bien servir le =~ dans la fonction de lecture ?" # on a regroupé en fonction un ensemble d'actions en relation echo "Des fonctions ..." # on créé un tableau qui contient une table d'élément indexé par position partant de 0. declare -a tableau # on va pas dire que c'etait très compliqué ... mon_fichier="le_beau_fichier.txt" saisie() { debut=$1 echo "Qu'est ce qui va nous arreter ?" read ARRET taille_tableau=${#tableau[@]} if [[ $debut > $taille_tableau ]] then debut=$taille_tableau fi for (( i=$debut ; $i < 20 ; i++ )) do index=$(( i + 1 )) echo "Tapez un truc pour voir... ($index)" read UNTRUC echo "$index) $UNTRUC" # etape 6 : il faut tester si UNTRUC vaut le contenu de ARRET : if [[ $UNTRUC == "$ARRET" ]] then break else tableau[$i]=$UNTRUC fi done } sauvegarde() { taille_tableau=${#tableau[@]} # >$mon_fichier créé un nouveau fichier echo "Oh le beau tableau qui va suivre" >$mon_fichier for (( i=0 ; $i < $taille_tableau ; i++ )) do contenu=${tableau[$i]} echo "$(( i + 1 )): $contenu" # >>$mon_fichier ( notez les deux > ) ajoute à la fin du fichier existant echo "$(( i + 1 )): $contenu" >>$mon_fichier if [[ "$toobad" == "stop" ]] then # les >&2 c'est pour écrire sur la sortie d'erreur et non sur la sortie standard. echo "Curieux, on aurait du s'arreter avant ..." >&2 elif [[ "$contenu" == "$ARRET" ]] then echo "Curieux, on aurait du ne pas enregistrer cette valeur puisque c'est la valeur d'arret..." >&2 toobad=stop fi done } lecture() { while read INDEX_UNTRUC do # Ah la beauté des expressions régulières qui ne s'appellent pas du tout comme ça en français, mais les informaticiens s'en fichent. # VARIABLE =~ regexp la VARIABLE a une suite de caractères qui peuvent se définir comme la regexp est écrite. # ici on extrait l'index avant les ':' car ce sont des nombres, et après le : il y a un espace ( que l'on 'échappe' par un \ ) puis on capture tout ce qui reste. if [[ $INDEX_UNTRUC =~ [0-9]*:\ (.*) ]] then # Oui BASH_REMATCH est un bashisme et est le résultat du =~ (.*) précédent, il contient ... le reste... UNTRUC=${BASH_REMATCH[1]} tableau[${#tableau[@]}]=$UNTRUC fi done < $mon_fichier } # le # indique un commentaire..., un commentaire est ignoré par bash mais très instructif pour ... nous les humains. lecture # maintenant on commence à partir de la fin ... taille_tableau=${#tableau[@]} saisie $taille_tableau sauvegarde echo "Voici ce que contient $mon_fichier:" cat $mon_fichier echo "Et si on décidait à partir de quel index on réécrit sur le fichier existant plutôt que de rajouter de la fin ?"