Mes notes pour scripts bash
- Mise Ă jour le 26 janv. 2021
Je mets ici mes notes pour la réalisation de scripts Bourne Shell dans un environnement GNU/Linux.
Les tableaux
Création
$ my_array=()
Ajouter un élément
$ element=banana
$ my_array+=($element)
Obtenir le nombre d'élément
$ echo "${#my_array[@]}"
Afficher le premier élément
$ echo "${my_array[0]}"
Afficher tous les éléments d'un tableau
x=0
while [ "$x" -lt "${#my_array[@]}" ]
do
echo "${my_array[$x]}"
x=$(( $x + 1 ))
done
for i in "${my_array[@]}"
do
echo "$i"
done
Opérations Arithmétiques
Exemples
- Addition 1 :
$ a=3
$ let a=a+1
$ echo $a
4
- Addition 2 :
$ a=3
$ a=$((a+1))
$ echo $a
4
Case… Esac
Structure
case $1 in
*.mp3) echo "$1 is a mp3 file";;
*.mkv) echo "$1 is a mkv file";;
*)
echo "$1 is an unknown"
echo "Format.";;
esac
Vérifier l'état de la dernière commande
if [ $? -eq 0 ] ; then
Les Opérateurs de Comparaison
- Comparaisons :
- String, Texte : =, !=, -n (non null), -z (null)
- Numérique : -eq (égal), -ne (non égal), -lt (moins que), -gt (plus grand que), -ge (plus grand ou égal)
- Logical operators : && (ET), || (OU), ! (NON)
- File : -f (si existe), -d (si répertoire), -s (taille non null), -x (si le fichier est exécutable)
For… Do… Done
Structure
- Exemple n°1 :
for x in 1 2 3
do
echo $x
done
- Exemple n°2 :
for s in www-0{1..8}
do
echo $s
done
Gérer les espaces dans une boucle for
Par défaut si l'on stocke, le résultat d'une commande à l'intérieur d'une variable, et que l'on effectue une boucle for sur cette variable, alors les espaces, tabulations et nouvelles lignes seront considérés comme des nouvelles lignes.
Voyons cela dans un exemple inutile mais concret.
- On place dans la variable text, un texte avec des espaces :
$ text="Body screaming fucking bloody mess"
- Si nous effectuons une boucle loop nous pouvons voir que les espaces ont été remplacés par de nouvelles lignes :
for i in $text; do
echo "$i"
done
Body
screaming
fucking
bloody
mess
C'est à cause de la valeur par défaut de l'IFS (Internal Field Separator) qui est : space, tab and newline.
Donc, pour éviter cela nous allons devoir le reparamétrer la variable IFS, pour indiquer que le champ de séparation ne doit être que pour les nouvelles lignes.
$ IFS=$'\n'
for i in $text; do
echo "$i"
done
Body screaming fucking bloody mess
If… Then… Else… Fi
Structure
if [ -s $1 ]
then
echo "$1 exist"
else
echo "$1 doesn't exist"
fi
Exemples
Si la variable est nulle
if [ ! -n "$var" ]; then
Double condition if
- Exemple n°1 :
if [ -n "$answer" ] && [ "$answer" != "N" ]; then
echo "OK"
fi
- Exemple n°2 :
if [ $(ssh user@192.168.1.200 mount | grep -q crypt_backup; echo $?) -eq "0" ] && [ $(ps -ef | grep -q [r]sync; echo $?) -ne "0" ] ; then
echo "OK"
fi
Manipuler du texte
Substitution
- % pour remplacer le suffixe. Ici on remplace l'extension du fichier :
$ FILE="The_Dolphins_-_Demo_-_Anemia.ogg"
$ echo "${FILE%.ogg}.mp3"
The_Dolphins_-_Demo_-_Anemia.mp3
- # pour remplacer le préfixe :
$ FILE="The_Dolphins_-_Demo_-_Anemia.ogg"
$ echo "${FILE#The_Dolphins_-_Demo_-_}"
Anemia.ogg
Commande expr
Exemple n°1
$ line="secure-policy rule: 1"
$ expr match "$line" '.*: \([0-9]\+\)'
1
Exemple n°2
$ line=" name: STD01_to_ZYXEL_SSH"
$ expr match "$line" '.*: \([a-zA-Z0-9_]\+\).*'
STD01_to_ZYXEL_SSH
Lire un fichier ligne par ligne
while IFS= read -r line
do
echo "$line"
done < /tmp/a_file.txt
Arréter un script sur erreurs
Source : https://wizardzines.com/
- Arréter le script sur une erreur
$ set -e
- Arréter le script si une variable n'est pas définit
$ set -u
- Arréter le script si échec dans un pipe
$ set -o pipefail
- Arréter le script sur une des erreurs définis ci dessus
$ set -euo pipefail
While… Do… Done
Structure
while [ $a -gt 0 ]
do
echo "a=$a"
let a=$a-1
done