## 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 ?"
