- Notes sur BASH
- Itérateur
- Tableaux
- Tableaux associatifs
- Tests sur les fichiers / dossiers
- Faire des calculs / $i++
- Fonctions
- Sortie en couleurs
- Debbuger un script
- S’assurer que les variables sont remplies avant d’être utilisées
- Sortir dès qu’une commande ne retourne pas un code de retour nul
- Code de retour en erreur transmis dans le pipe
- Les N premières ou dernières lignes
- Tout SAUF les N premières ou les N dernières lignes
Ce contenu est fourni sous licence CC BY-NC-SA 4.0
Notes sur BASH
Itérateur
# faire un boucle de 1 à 9 :
for i in $(seq 0 9)
do
...
done
Tableaux
# déclarer un tableau
declare -a tableau
tableau=( "des pommes" "des poires")
# taille du tableau
echo "taille du tableau : ${#tableau[@]}"
# ajouter un élément au tableau :
tableau[2]="et des scoubidoubidou ouah"
# afficher un élément du tableau
echo "tableau : 0 : ${tableau[0]}"
echo "tableau : 1 : ${tableau[1]}"
echo "tableau : 2 : ${tableau[2]}"
# obtenir la liste des indices du tableau :
echo "les indices sont : ${!tableau[@]}"
# parcourir les éléments du tableau et les afficher :
for i in ${!tableau[@]}
do
echo "dans le tableau $i : ${tableau[$i]}"
done
Le résultat :
taille du tableau : 2
tableau : 0 : des pommes
tableau : 1 : des poires
tableau : 2 : et des scoubidoubidou ouah
les indices sont : 0 1 2
dans le tableau 0 : des pommes
dans le tableau 1 : des poires
dans le tableau 2 : et des scoubidoubidou ouah
Tableaux associatifs
# déclarer un tableau associatif
declare -A tableau_associatif
tableau_associatif=( [prenom]="Cedric" [nom]="Temple" [os]="GNU/Linux Debian" [taille]="1m83" )
# taille du tableau
echo "taille du tableau : ${#tableau_associatif[@]}"
# ajouter un élément au tableau :
tableau_associatif['age']="il a atteint un age à partir duquel c'est impoli de demander"
# taille du tableau
echo "nouvelle taille du tableau après ajout : ${#tableau_associatif[@]}"
# afficher un élément du tableau
echo "tableau : 'prenom' : ${tableau_associatif['prenom']}"
echo "tableau : 'nom' : ${tableau_associatif['nom']}"
echo "tableau : 'age' : ${tableau_associatif['age']}"
# obtenir la liste des indices du tableau :
echo "les indices sont : ${!tableau_associatif[@]}"
# parcourir les éléments du tableau et les afficher :
for i in ${!tableau_associatif[@]}
do
echo "dans le tableau $i : ${tableau_associatif[$i]}"
done
Le résultat :
taille du tableau : 4
nouvelle taille du tableau après ajout : 5
tableau : 'prenom' : Cedric
tableau : 'nom' : Temple
tableau : 'age' : il a atteint un age à partir duquel c'est impoli de demander
les indices sont : os age taille prenom nom
dans le tableau os : GNU/Linux Debian
dans le tableau age : il a atteint un age à partir duquel c'est impoli de demander
dans le tableau taille : 1m83
dans le tableau prenom : Cedric
dans le tableau nom : Temple
Tests sur les fichiers / dossiers
# vérifier qu'un élément existe
if [ -e ${FILE} ]
# vérifier qu'un élément existe et est un fichier (pas un dossier, ni un lien symbolique, ni ...)
if [ -f ${FILE} ]
# vérifier qu'un élément existe et est un répertoire / directory
if [ -d ${FILE} ]
# vérifier qu'un élément existe et est un lien symbolique
if [ -d ${FILE} ]
# vérifier qu'un élément existe et que sa taille est strictement positive
if [ -s ${FILE} ]
# vérifier qu'un élément existe et que cet élément a le droit de lecture positionné
if [ -r ${FILE} ]
# vérifier qu'un élément existe et que cet élément a le droit en écriture positionné
if [ -w ${FILE} ]
# vérifier qu'un élément existe et que cet élément a le droit d'exécution positionné
if [ -x ${FILE} ]
Faire des calculs / $i++
C’est toujours utile de pouvoir incrémenter une variable à l’aide de quelque chose comme $i++. En bash, ce n’est pas si simple.
let i=0
...
...
let i++
Pour faire un calcul :
let A=10
let B=2
let C=A+B
Fonctions
mafonction() {
ls
echo
# ...
}
mafonction
mafonction_avec_parametres() {
# on déclare les variables en local pour ne pas rentrer
# en conflit avec les variables déclarées par ailleurs
local monPremierParametre=$1
local monDeuxiemeParametre=$2
local monTroisiemeParametre=$3
# ...
}
mafonction_avec_parametres valeur1 valeur2 valeur3
une_autre_fonction(){
local nombreTotalParametre=$#
# ...
return 12
}
une_autre_fonction monParametre
retour=$?
# retour va avoir la valeur renvoyée par la fonction
Sortie en couleurs
Afficher du texte en couleurs permet d’améliorer la lecture des informations affichées à l’utilisateur. C’est grandement utile et ça facile la compréhension de l’utilisateur.
TEXT_GREEN="32"
TEXT_RED="31"
TEXT_BLUE="34"
TEXT_YELLOW="93"
TEXT_WHITE="37"
TEXT_BLACK="30"
TEXT_BOLD="1"
TEXT_UNDERLINE="4"
TEXT_BLINK="5"
TEXT_REVERSE="7" # inverse background and text color
TEXT_HIDDEN="8" # very useful for secrets/passwords
TEXT_RESET="0"
echo_with_colors(){
local text=$1
local color=$2
local no_trailing_newline=0
if [ $# -eq 3 ]
then
no_trailing_newline=1
fi
if [ ${no_trailing_newline} -eq 0 ]
then
echo -e "\e[${color}m${text}\e[${TEXT_RESET}m"
else
echo -n -e "\e[${color}m${text}\e[${TEXT_RESET}m"
fi
}
echo_with_colors "TEXT in GREEN" "${TEXT_GREEN}"
echo_with_colors "TEXT in GREEN without trailing newline" "${TEXT_GREEN}" 1
echo_with_colors "TEXT in RED" "${TEXT_RED}"
echo_with_colors "TEXT in RED and BOLD" "${TEXT_RED};${TEXT_BOLD}"
echo_with_colors "BACKGROUND in RED" "${TEXT_RED};${TEXT_REVERSE}"
Debbuger un script
Permet de voir les commandes telles que lancées par le script :
#!/bin/bash -x
let A=10
let B=2
let C=A+B
Exemple de sortie :
+ let A=10
+ let B=2
+ let C=A+B
+ echo 12
12
Si on ne veut pas modifier le script pour ajouter l’option définitivement mais juste le faire de temps en temps :
bash -x monscript.sh
Si on veut debbuger une petite partie du script :
#!/bin/bash
...
...
set -x # le debug commence ici
...
...
set +x # le debug termine ici
...
Pour le mettre de façon plus explicite :
#!/bin/bash
...
set -o xtrace # le debug commence ici
...
set +o xtrace # le debug s'arrête ici
S’assurer que les variables sont remplies avant d’être utilisées
#!/bin/bash -u
# ou :
set -u
# ou :
set -o nounset
Exemple :
#!/bin/bash -xu
A=1
B=2
echo $A
echo $B
# on fait exprès d'utiliser une variable non initialisée pour générer une erreur
echo $C
Affichage :
+ A=1
+ B=2
+ echo 1
1
+ echo 2
2
./test.sh: ligne 8: C : variable sans liaison
Sortir dès qu’une commande ne retourne pas un code de retour nul
Petit rappel préalable : toute commande qui ne sort pas avec un code de retour nul indique qu’elle sort en erreur.
#!/bin/bash -e
# ou
set -e
# ou
set -o errexit
Exemple de script shell :
#!/bin/bash -xe
echo "A"
(exit 0)
echo "B"
(exit 1)
echo "C"
Le résultat de ce script montre que lorsque la commande en sous shell (celle dans des parenthèses) renvoie un code de retour nul, le shell continue alors que si le code de retour est non nul, le shell s’arrête (la dernière commande affichant C n’est pas exécutée) :
+ echo A
A
+ exit 0
+ echo B
B
+ exit 1
Code de retour en erreur transmis dans le pipe
set -o pipefail
Quelques explications. Par défaut, si une commande échoue dans un pipe, le traitement se poursuit. Exemple (bâteau) pour démontrer le problème :
#!/bin/bash
echo "erreur" | while read a; do if [ $a == "erreur" ]; then echo "ERREUR"; exit 127; fi; done | (read b ; echo "B : $b")
echo $?
Ce qui donne :
B : ERREUR
0
Ci-dessus, nous voyons que le traitement continue et que le code de retour final est 0. Parfois, on préfère arrêter le traitement et avoir comme code de retour final le code d’erreur.
Une option permet d’obtenir en résultat de tout le pipe, le code d’erreur (différent de 0 évidemment) le plus à droite du pipe :
set -o pipefail
Exemple quand on ajoute cette option :
#!/bin/bash
set -o pipefail
echo "erreur" | while read a; do if [ $a == "erreur" ]; then echo "ERREUR"; exit 127; fi; done | (read b ; echo "B : $b")
echo $?
Le résultat est :
B : ERREUR
127
Maintenant, si on veut que le traitement s’arrête : #!/bin/bash
set -o pipefail
set -o errexit
echo "erreur" | while read a; do if [ $a == "erreur" ]; then echo "ERREUR"; exit 127; fi; done | (read b ; echo "B : $b")
echo $?
Le résultat est :
B : ERREUR
À noter : le traitement dans le pipe se continue malgré les erreurs intermédiaires.
Les N premières ou dernières lignes
# les 20 premières lignes :
ls /usr/bin | head -n 20
# les 20 dernières lignes :
ls /usr/bin | tail -n 20
Tout SAUF les N premières ou les N dernières lignes
# ATTENTION !!! La syntaxe est (je trouve) particulière.
# A titre personnel, j'inverse toujours head/tail...
# ... et je ne me souviens jamais s'il faut mettre + ou -
# tout SAUF les 5 premières lignes : ajouter +1
# en fait, c'est "afficher tout à partir de la Nieme ligne" où N est ici la 6e ligne
ls /usr/bin | tail -n +6
# tout SAUF les 5 dernières lignes :
ls /usr/bin | head -n -5
Ce contenu est fourni sous licence CC BY-NC-SA 4.0