BASH - Mémo pour scripter
Table des matières
Je script, je script, mais parfois, j'ai un sacré trou de mémoire ... et je galère à trouver ce que je cherche sur Internet.
Comment on incrémente une variable ? Comment on fait un SI, un POUR ?
Et bien la réponse se trouve ci-dessous !
Pour mettre dans la variable a la valeur chaîne toto :
De la même façon, on peut mettre dans des variables des nombres :
Pour utiliser ces variables, ajouter un $ devant :
On peut l'appeler en l'encadrant avec ${} :
On peut aussi afficher la longueur de cette variable avec ${#var} :
On peut mettre dans une variable le résultat d'une commande shell en encadrant la commande dans $() :
On pourra veiller à déclarer correctement les variables avec la commande declare pour forcer le type :
On peut faire du 2 en 1 évidemment : déclarer et affecter
Il existe quelques variables spéciales :
$$ : PID du shell courant
$! : PID du dernier travail lancé en arrière plan
$? : code retour de la dernière commande
Et d'autres variables prédéfinies, dites variables d'environnement :
$HOME chemin du répertoire personnel de l'utilisateur
$OLDPWD chemin du répertoire précédent
$PATH liste des chemins de recherche des commandes exécutables
$PPID PID du processus père du shell
$PS1 invite principale du shell
$PWD chemin du répertoire courant
$RANDOM nombre entier aléatoire compris entre 0 et 32767
$REPLY variable par défaut de la commande "read" et de la structure shell "select"
$SECONDS nombre de secondes écoulées depuis le lancement du shell
Grosso-modo, pour faire des calculs simples, on utilise la syntaxe suivante :
On peut affecter ce calcul à une variable :
Ou bien l'afficher :
Si on veut faire une addition :
Si on veut faire une soustraction :
Si on veut faire une multiplication :
Si on veut faire une division :
On peut évidemment utiliser des variables dans le calcul :
Pour incrémenter ou décrémenter, on peut utiliser la fonction let :
Le test "Si'" est généralement fait ainsi :
Pour les exemples, nous avons besoin d'opérateurs de comparaison, voir ci-dessous.
-eq : est égal à
-ne : n'est pas égal à
-gt : est plus grand que
-ge : est plus grand ou égal à
-lt : est plus petit que
-le : est plus petit ou égal à
== : est égal à
!= : n'est pas égal à
-z string : Vrai si la longueur de la chaîne est égale à 0 (variable non initialisée)
=~ : match avec une regexp.
Exemple, si la variable contient "cou" :
Exemple, si ça commence par un a :
-z $var : Vrai si la taille de la chaîne est zéro (variable non utilisée ou vide)
-n $var : Vrai si la taille de la chaîne est différente de zéro (variable utilisée et non vide)
-e file : Vrai si le fichier existe
-d file : Vrai si le fichier existe et que c'est un répertoire
-f file : Vrai si le fichier existe et que c'est un fichier ordinaire
-h file : Vrai si le fichier existe et que c'est un lien symbolique
-r file : Vrai si le fichier possède les droits de lecture
-s file : Vrai si le fichier a une taille non nulle
-w file : Vrai si le fichier possède les droits d'écriture
-x file : Vrai si le fichier possède les droits d'exécution
-O file : Vrai si le possesseur est identique à celui qui exécute le test
-G file : Vrai si le possesseur qui exécute le test fait partie du groupe du fichier
-N file : Vrai si le fichier existe et qu'il a été modifié depuis sa dernière lecture
file1 -nt file2 : Vrai si le file1 est plus récent que file2 (date de modification) ou si file1 existe et pas file2
file1 -ot file2 : Vrai si file1 est plus ancien que file2 ou que file2 existe et pas file1
Le symbole de négation est !.
Si on teste de cette façon su un dossier existe :
Et bien tester s'il existe pas se fera ainsi :
Si vous voulez combiner des tests (le ET ou bien le OU) c'est avec -a et -o :
Pour le ET :
Pour le OU :
Pour le for ce n'est pas très compliqué :
On peut traiter avec une commande aussi, par exemple la boucle ci-dessus peut être écrite en utilisant la commande seq :
Et on peut aussi utiliser des chaines de caractère :
Pour la boucle infinie, utiliser ceci (fin de la boucle avec break) ou CTRL+C :
De manière générale, la syntaxe est la suivante :
Voici un exemple :
La boucle infinie se traduit ainsi :
La boucle infinie peut s’interrompre avec break :
Il est possible d'utiliser les tableaux en bash !
Affectation du premier enregistrement du tableau "tab" :
Contenu du premier enregistrement du tableau "tab" :
ou
Contenu du douzième enregistrement du tableau "tab" (oui ça commence à 0) :
Ensemble des enregistrements du tableau "tab" :
Longueur du douzième enregistrement du tableau "tab" :
Nombre d'enregistrements du tableau "tab" :
Pour lire les lignes d'un fichier :
Si on veut lire un fichier avec des lignes avec un séparateur (exemple passwd, qui a le séparateur : ) on peut stocker direct dans les variables
Pour vérifier si le script est lancé en root, on peut utiliser ce petit morceau de code qui va vérifier la variable EUID :
Si vous voulez demander à l'utilisateur de taper du texte, et de récupérer le contenu dans une variable, c'est possible. C'est la commande read :
Ici, stockons le résultat de la saisie dans la variable texte :
Avec l'option -p on pourra même mettre un message avant la saisie (qui se sera pas inclus dans le contenu de la variable) :
Tous se passe dans le code retour de la commande.
Exemple avec ls. La page man indique les différents codes retour :
Ce code est stocké dans la variable $? :
Voyons un exemple avec un succès (même si je n'ai rien dans /mnt, la commande n'a rencontré aucune erreur, le code vaut donc 0) :
Ici un exemple avec un répertoire inexistant (le code vaut 2) :
Pour agrémenter vos scripts, vous pouvez mettre de la couleur.
Voici une liste des couleurs possibles (ici j'affecte à des variables les codes couleur) :
Dans un code de type \033[0;31m pour le rouge, vous pouvez remplacer le 0 après le crochet ouvrant indique le style du texte.
0 : Standard
1 : Gras
2 : Ca semble plus foncé
3 : Italique
4 : Souligné
5 : Clignotant
7 : Surligné
9 : Barré
Voici un exemple en rouge et gras (notez l'usage de l'option -e de echo) :
Introduction
Je script, je script, mais parfois, j'ai un sacré trou de mémoire ... et je galère à trouver ce que je cherche sur Internet.
Comment on incrémente une variable ? Comment on fait un SI, un POUR ?
Et bien la réponse se trouve ci-dessous !
Les variables
Affectation de variable
Pour mettre dans la variable a la valeur chaîne toto :
Code BASH :
a="toto"
De la même façon, on peut mettre dans des variables des nombres :
Code BASH :
b=2
Pour utiliser ces variables, ajouter un $ devant :
Code BASH :
echo $a
Code :
toto
On peut l'appeler en l'encadrant avec ${} :
Code BASH :
echo ${a}
Code :
toto
On peut aussi afficher la longueur de cette variable avec ${#var} :
Code TEXT :
echo ${#a} toto
On peut mettre dans une variable le résultat d'une commande shell en encadrant la commande dans $() :
Code BASH :
nb=$(ls -l /etc | wc -l)
Code BASH :
echo $nb 342
On pourra veiller à déclarer correctement les variables avec la commande declare pour forcer le type :
Code BASH :
declare -r variableEnLectureSeule declare -i entier declare -a tableau
On peut faire du 2 en 1 évidemment : déclarer et affecter
Code BASH :
declare -i nb=42
Variables spéciales
Il existe quelques variables spéciales :
$$ : PID du shell courant
$! : PID du dernier travail lancé en arrière plan
$? : code retour de la dernière commande
Et d'autres variables prédéfinies, dites variables d'environnement :
$HOME chemin du répertoire personnel de l'utilisateur
$OLDPWD chemin du répertoire précédent
$PATH liste des chemins de recherche des commandes exécutables
$PPID PID du processus père du shell
$PS1 invite principale du shell
$PWD chemin du répertoire courant
$RANDOM nombre entier aléatoire compris entre 0 et 32767
$REPLY variable par défaut de la commande "read" et de la structure shell "select"
$SECONDS nombre de secondes écoulées depuis le lancement du shell
Calculs
Calculs simples
Grosso-modo, pour faire des calculs simples, on utilise la syntaxe suivante :
Code BASH :
$((calcul))
On peut affecter ce calcul à une variable :
Code BASH :
a=$((calcul))
Ou bien l'afficher :
Code BASH :
echo $((calcul))
Si on veut faire une addition :
Code BASH :
echo $((21+21)) 42
Si on veut faire une soustraction :
Code BASH :
echo $((63-21)) 42
Si on veut faire une multiplication :
Code BASH :
echo $((2*21)) 42
Si on veut faire une division :
Code BASH :
echo $((84/2)) 42
On peut évidemment utiliser des variables dans le calcul :
Code BASH :
i=42 echo $(($i*2)) 84
Incrémenter et décrémenter
Pour incrémenter ou décrémenter, on peut utiliser la fonction let :
Code BASH :
i=42 let i-- echo $i 41
Code BASH :
let i++ echo $i 42
Les structures conditionnelles : If
Le test "Si'" est généralement fait ainsi :
Code BASH :
if condition then commande 1 commande2 fi
Pour les exemples, nous avons besoin d'opérateurs de comparaison, voir ci-dessous.
Les opérateurs de comparaison
Comparaison d'entiers
-eq : est égal à
Code BASH :
if [ "$a" -eq "$b" ]
-ne : n'est pas égal à
Code BASH :
if [ "$a" -ne "$b" ]
-gt : est plus grand que
Code BASH :
if ["$a" -gt "$b" ]
-ge : est plus grand ou égal à
Code BASH :
if [ "$a" -ge "$b" ]
-lt : est plus petit que
Code BASH :
if [ "$a" -lt "$b" ]
-le : est plus petit ou égal à
Code BASH :
if [ "$a" -le "$b" ]
Comparaison de chaînes
== : est égal à
Code BASH :
if [ "$a" == "$b" ]
!= : n'est pas égal à
Code BASH :
if [ "$a" != "$b" ]
-z string : Vrai si la longueur de la chaîne est égale à 0 (variable non initialisée)
Code BASH :
if [ -z "$var" ]
Match de chaine
=~ : match avec une regexp.
Exemple, si la variable contient "cou" :
Code BASH :
if [[ "$a" =~ cou ]]
Exemple, si ça commence par un a :
Code BASH :
if [[ "$a" =~ ^a ]]
Les tests sur les chaines
-z $var : Vrai si la taille de la chaîne est zéro (variable non utilisée ou vide)
Code BASH :
if [ -z $var ]
-n $var : Vrai si la taille de la chaîne est différente de zéro (variable utilisée et non vide)
Code BASH :
if [ -n $var ]
Les tests sur les fichiers
-e file : Vrai si le fichier existe
Code BASH :
if [ -e /tmp/fichier ]
-d file : Vrai si le fichier existe et que c'est un répertoire
Code BASH :
if [ -d /tmp/dossier ]
-f file : Vrai si le fichier existe et que c'est un fichier ordinaire
Code BASH :
if [ -f /tmp/fichier ]
-h file : Vrai si le fichier existe et que c'est un lien symbolique
Code BASH :
if [ -h /tmp/lien ]
-r file : Vrai si le fichier possède les droits de lecture
Code BASH :
if [ -r /tmp/fichier ]
-s file : Vrai si le fichier a une taille non nulle
Code BASH :
if [ -s /tmp/fichier ]
-w file : Vrai si le fichier possède les droits d'écriture
Code BASH :
if [ -w /tmp/fichier ]
-x file : Vrai si le fichier possède les droits d'exécution
Code BASH :
if [ -x /tmp/fichier ]
-O file : Vrai si le possesseur est identique à celui qui exécute le test
Code BASH :
if [ -O /tmp/fichier ]
-G file : Vrai si le possesseur qui exécute le test fait partie du groupe du fichier
Code BASH :
if [ -G /tmp/fichier ]
-N file : Vrai si le fichier existe et qu'il a été modifié depuis sa dernière lecture
Code BASH :
if [ -N /tmp/fichier ]
Comparaison de fichiers
file1 -nt file2 : Vrai si le file1 est plus récent que file2 (date de modification) ou si file1 existe et pas file2
Code BASH :
if [ file1 -nt file2 ]
file1 -ot file2 : Vrai si file1 est plus ancien que file2 ou que file2 existe et pas file1
Code BASH :
if [ file1 -ot file2 ]
La négation (inverser le test)
Le symbole de négation est !.
Si on teste de cette façon su un dossier existe :
Code BASH :
if [ -d "$DIR" ]
Et bien tester s'il existe pas se fera ainsi :
Code BASH :
if [ ! -d "$DIR" ]
Et Ou
Si vous voulez combiner des tests (le ET ou bien le OU) c'est avec -a et -o :
Pour le ET :
Code BASH :
if ["$a" -gt "$b" -a "$c" -gt "$d"]
Pour le OU :
Code BASH :
if ["$a" -gt "$b" -o "$c" -gt "$d"]
Les structures conditionnelles Partie 2
For
Pour le for ce n'est pas très compliqué :
Code BASH :
for i in 1 2 3 4 5 do echo $i commande1 commande2 commandeN done
On peut traiter avec une commande aussi, par exemple la boucle ci-dessus peut être écrite en utilisant la commande seq :
Code BASH :
for i in $(seq 1 5) do echo $i commande1 commande2 commandeN done
Et on peut aussi utiliser des chaines de caractère :
Code BASH :
for f in fic1 fic2 fic3 do echo "On affiche le fichier $f" cat $f done
Pour la boucle infinie, utiliser ceci (fin de la boucle avec break) ou CTRL+C :
Code BASH :
for (( ; ; )) do echo "boucle infinie" done
While
De manière générale, la syntaxe est la suivante :
Code BASH :
while [ condition ] do commande1 commande2 commande3 done
Voici un exemple :
Code BASH :
x=1 while [ $x -le 5 ] do echo "Passage numéro $i" x=$(($x+1)) done
La boucle infinie se traduit ainsi :
Code BASH :
while : do echo "boucle infinie" done
La boucle infinie peut s’interrompre avec break :
Code BASH :
while : do read -p "Entrer un chiffre ( -1 pour quitter ) : " a if [ $a -eq -1 ] then break fi echo "Vous avez saisi $a" done
Les tableaux
Il est possible d'utiliser les tableaux en bash !
Affectation du premier enregistrement du tableau "tab" :
Code BASH :
tab[0]=val
Contenu du premier enregistrement du tableau "tab" :
Code BASH :
echo ${tab[0]}
ou
Code BASH :
echo $tab
Contenu du douzième enregistrement du tableau "tab" (oui ça commence à 0) :
Code BASH :
echo ${tab[11]}
Ensemble des enregistrements du tableau "tab" :
Code BASH :
echo ${tab[*]}
Longueur du douzième enregistrement du tableau "tab" :
Code BASH :
echo ${#tab[11]}
Nombre d'enregistrements du tableau "tab" :
Code BASH :
echo ${#tab[*]}
Des petits trucs marrants
Lire un fichier ligne par ligne
Pour lire les lignes d'un fichier :
Code BASH :
while read ligne do echo "$ligne" done < fichier
Si on veut lire un fichier avec des lignes avec un séparateur (exemple passwd, qui a le séparateur : ) on peut stocker direct dans les variables
Code BASH :
while IFS=: read user pass uid gid nom dossperso shell do echo "$user avec UID $uid a son home dans $dossperso" done < /etc/passwd
Vérifier si on est root
Pour vérifier si le script est lancé en root, on peut utiliser ce petit morceau de code qui va vérifier la variable EUID :
Code BASH :
if [[ $EUID -ne 0 ]] then echo "Doit être lancé en root" exit 1 fi
Lire une variable depuis une saisie du clavier
Si vous voulez demander à l'utilisateur de taper du texte, et de récupérer le contenu dans une variable, c'est possible. C'est la commande read :
Ici, stockons le résultat de la saisie dans la variable texte :
Code BASH :
read texte
Avec l'option -p on pourra même mettre un message avant la saisie (qui se sera pas inclus dans le contenu de la variable) :
Code BASH :
read -p "Saisir un mot : " texte
Vérifier le bon déroulement d'une commande
Tous se passe dans le code retour de la commande.
Exemple avec ls. La page man indique les différents codes retour :
Code TEXT :
0 si OK, 1 si problèmes mineurs (par exemple, impossible d'accéder à un sous-répertoire), 2 si erreur grave (par exemple, impossible d'accéder aux pa‐ ramètres de la ligne de commande).
Ce code est stocké dans la variable $? :
Voyons un exemple avec un succès (même si je n'ai rien dans /mnt, la commande n'a rencontré aucune erreur, le code vaut donc 0) :
Code BASH :
ls /mnt echo $? 0
Ici un exemple avec un répertoire inexistant (le code vaut 2) :
Code BASH :
ls /existepas ls: impossible d'accéder à '/existepas': Aucun fichier ou dossier de ce type echo $? 2
Mettre le texte en couleur
Pour agrémenter vos scripts, vous pouvez mettre de la couleur.
Voici une liste des couleurs possibles (ici j'affecte à des variables les codes couleur) :
Code BASH :
# Réinitialisation de la couleur après cette balise COLOR_RESET='\033[0m' # Codes couleurs à placer avant le texte : COLOR_NOIR='\033[0;30m' COLOR_ROUGE='\033[0;31m' COLOR_VERT='\033[0;32m' COLOR_JAUNE='\033[0;33m' COLOR_BLEU='\033[0;34m' COLOR_VIOLET='\033[0;35m' COLOR_CYAN='\033[0;36m' COLOR_BLANC='\033[0;37m'
Dans un code de type \033[0;31m pour le rouge, vous pouvez remplacer le 0 après le crochet ouvrant indique le style du texte.
0 : Standard
1 : Gras
2 : Ca semble plus foncé
3 : Italique
4 : Souligné
5 : Clignotant
7 : Surligné
9 : Barré
Voici un exemple en rouge et gras (notez l'usage de l'option -e de echo) :
Code BASH :
echo -e '\033[1;31m' ROUGE '\033[0m'