Scripts et Programmation

BASH - Mémo pour scripter

Cet article a été mis à jour, vous consultez ici une archive de cet article!
Table des matières

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'