Bash scripting
Documentations > Langages
Posté le 16 novembre 2018 dans Langages par Julien.
Concevez des scripts qui exĂ©cutent des commandes de type "terminal" đ„
Le shell scripting avec Bash
Un Shell est une interface utilisateur du systĂšme d’exploitation. Il est la plus haute des interfaces des systĂšmes Unix, par opposition Ă la couche de bas-niveau, appelĂ©e Noyau.
Il existe plusieurs Shells qui sont tous basés sur SH. Bash est celui utilisé par la plupart des systÚmes GNU/Linux.
Le Shell Scripting permet d’automatiser des commandes du terminal, Ă l’aide d’une programmation qui reste limitĂ©e.
Executable Shebang
#!/bin/bash
# Executable shebang
# La premiere ligne n'est pas un commentaire ;)
# Elle specifie que le fichier s'execute avec bash
# (donc l'extention de fichier n'est plus obligatoire)
echo "test"
Ajouter le droit d’execution
chmod +x script_shebang
Ă la place du shebang on peut utiliser la commande …
bash /chemin/vers/le/script.sh
Les variables
# Il n'y a pas de typage, tout est chaine de caracteres
# Exemple de commande -> /bin/echo -e "Hello"
# $0 => /bin/echo
# $1 => "-e"
# $2 => "Hello"
# $* => "-e 'Hello'"
# $# => 2
var="variable var"
echo $var # $ Permet d'afficher la valeur de la variable
unset var # detruit la variable
echo $var
var=$1 # Affiche le premier argument de la commande
echo $var
var=$* # Affiche tous les arguments
echo $var
echo ${var}
echo "$var"
echo '$var' # Les simples quotes affichent le nom de la variable dans ce cas
echo ${var:2} # Recupere la chaine en supprimant les 2 premiers carateres
echo ${var:2:4} # Recupere 4 caractere a partir du 3eme inclus
echo ${#var} # Longeur de la variable
Ătat de sortie
# Etats de sortie:
# 0 -> OK
# Autre -> Code erreur pour le programme
echo "salut"
echo $? # Obtenir l'etat de sortie de la commande precedente ( => 0)
dfghjklpoiuyfvki
echo $? # retourne le code erreur (commande introuvable) ( => 127)
exit 123
# Si on fait echo $? apres la fermeture du script, on aura 123
echo "cette commande ne sera pas executee"
Conditions (Bash tests)
############# Chaines #############
# c1 = c2, vrai si c1 et c2 sont egaux
# c1 != c2, vrai si c1 et c2 sont différents
# -z c, vrai si c est la chaine vide
# -n c, vrai si c n'est pas la chaine vide
############# Pour les nombres #############
# n1 -eq n2, vrai si n1 et n2 sont egaux (equal)
# n1 -ne n2, vrai si n1 et n2 sont differents (non equal)
# n1 -lt n2, vrai si n1 est strictement inferieur a n2 (lower than)
# n1 -le n2, vrai si n1 est inferieur ou egal a n2 (lower or equal)
# n1 -gt n2, vrai si n1 est strictement superieur n2 (greater than)
# n1 -ge n2, vrai si n1 est superieur ou egal n2 (greater or equal)
############# Pour les expressions #############
# ! e, vrai si e est faux
# e1 -a e2, vrai si e1 et e2 sont vrais
# e1 -o e2, vrai si e1 ou e2 est vrai
test 4 -gt 3
echo $? # => 0 DONC VRAI !!! (pas comme d'hab car "etat de sortie bash"..)
test 4 -lt 3
echo $? # => 1 DONC FAUX !!!
# Une autre ecriture, attention aux espaces vers les crochets
[ 4 -gt 3 ] && echo $?
############# if #############
var=3
if [ $var -lt 3 ]; then
echo '$var -lt 3'
elif [ $var -le 3 ]; then
echo '$var -le 3'
else
echo 'else'
fi
if [ $var = 3 ]; then echo "'=' sert aussi a comparer"; fi
############# case #############
case $var in
1|2)
echo '$var vaut 2 ou 3'
;;
3|4)
echo '$var vaut 3 ou 4'
;;
5)
echo '$var vaut 5'
;;
*)
echo '$var vaut... autre chose...'
;;
esac
############# COMPOSITION #############
# cmd1 ; cmd2 Sequentielle
# cmd1 & cmd2 Parallele
# cmd1 || cmd2 Sur erreur
# cmd1 && cmd2 Sur succes
[ $var ] && echo 123 || echo "probleme chef'"
[ $varnull ] && echo 123 || echo "probleme chef'"
Opérations
############# Operateurs #############
# + Addition
# - Soustraction
# * Multiplication
# ** Puissance (Bash > 2.02)
# / Division
# % Modulo
# Bash ne supporte pas les nombres a virgule !!! 2/5
# Pour des calcules plus complexes voir le langage bc (man bc)
############# Affectation arithmetique #############
# +=
# -=
# *=
# /=
# %= (Affectation du reste de la division)
############# Operateurs binaires #############
# << decalage d'un bit a gauche (multiplication par 2) # >> decalage d'un bit a droite (division par 2)
# & ET binaire
# | OU Inclusif binaire
# ~ NON binaire
# ^ XOR (ou exclusif) binaire
# Ils peuvent etre associes a l'affectation <<= # Le symbole ! permet d'inverser le retour ############# Changement de base ############# # Nombre precede de 0 -> base 8 (Attention! 06443->base8)
# Nombre precede de 0x -> base 16
# Autres bases : BASE# Ex: 64#...
############# Calculs #############
# let 'var = 3+2'
# ou doubles parentheses -> bc plus de fonctionnalites
# (( var = 3+2 )) ou (( var++ )) ou echo $(( var = 3**2 ))
let 'var=5+2'; echo $var # -> 7
(( resultat = 5/2 ))
echo $resultat
(( entier = 5/2 )) ; (( reste = 5%2 ))
echo "entier -> $resultat"
echo "reste -> $reste"
(( entier = 5/2, reste = 5%2 ))
echo "entier -> $resultat - reste -> $reste" # -> entier 2 - reste 1
Boucles
############# FOR #############
# for var in list
# do
# echo $var
# done
#
# for (( i=1 ; i<=5 ; i++ )) # /!\ ce n'est pas une evaluation arithmetique # do # echo $i # done ############# WHILE ############# # while cmd # do # echo "coucou" # done ############# UNTIL ############# # until cmd # do # echo "coucou" # done ############# Controle de boucle ############# # break -> sortir de la boucle.
# break 2 -> sortir de 2 niveau de boucles
# continue -> tour de boucle suivant
############# Exemple #############
user_entry=""
while [ "$user_entry" != "coucou" ]
do
read -p "Vas-y ecris 'coucou' ;) : " user_entry
done
echo "T'es trop fort !"
user_entry2=""
until [ "$user_entry2" = "coucou" ]
do
read -p "Vas-y ecris 'coucou' ;) : " user_entry2
done
echo "T'es trop fort !"
for couleur in bleu blanc rouge
do
echo $couleur
done
for (( i=0 ; i<10 ; i++ ))
do
echo $i
if [ $i -ge 3 ]; then
break
fi
done
Substitution de commande
# Syntaxe : `ma commande` ou $(ma commande)
# Attention c'est ` et PAS CA " ou CA ' ou CA â ou CA â
# [ -x `wich bash` ]
# for i in `seq 1 100` ; do
# variable=`<fichier` ou variable=`cat fichier`
# (moins performant avec cat car nouveau process)
Documents intégrés
# Utile pour manipuler une application
vim fichier <<EOT
i
blah blah blah
^[
:wq !
EOT
# Pour ne pas interpreter les tabulations:
# cat <<-EOT ......
Sous-shells et shells restreints
# On a 3 shells qui sont complettement independants
# 1 shell 'racine' et 2 'sous-shells'
pwd
( cd / ; pwd ) & ( cd /etc ; pwd )
pwd
# Le mode restreint permet de gagner en securite
# Au sens large. CAD qu'il empeche :
# - Sortir du repertoire de travail (cd)
# - Changement de valeur des variables d'environnement ($PATH, $SHELL, $BASH_ENV, $ENV)
# - Lecture et remplacement d'options d'options d'environnement des shell $SHELLOPTS
# - Redirection de sortie
# - Appel de commandes contenants un ou plusieurs /
# - Substituer un processus different de celui du shell (exec)
# - Sortir du mode restreint au sain du script
set -r
cd .. # -> Erreur
Fonctions
function ma_fonction_1
{
echo "Syntaxe 1"
echo $1 $2
return 123
}
ma_fonction_2 ()
{
echo "Syntaxe 2"
echo $1 $2
# return "retour f2"
# -> erreur seulement des nombres en return
}
ma_fonction_1 "arg 1" "arg 2" || echo $? # 123
echo "----"
ma_fonction_2 "arg 1" "arg 2"
Alias
# Les alias sont utilises sont des raccourcis
# Utilises dans .bashrc par exemple
alias JuJu="ls"
JuJu # effectue un ls
unalias JuJu # Penser a suppr l'alias
Source (include)
# Inclure un fichier dans un autre
# Comme si on faisait un copier/coller
source mon_fichier # Syntaxe 1
. mon_fichier_2 # Syntaxe 2
Listes et tableaux
# Les tableau de bash sont plutot
# des listes, car pas de taille fixe
tab=("val1" "val2" "val3")
echo ${tab[0]} # -> val1
echo ${tab[1]} # -> val2
echo ${tab[2]} # -> val3
tab[0]="nouvelle valeur"
echo ${tab[0]} # -> nouvelle valeur
echo ${#tab[@]} # -> 3 (longeur du tab)
echo ${#tab[*]} # -> 3 (IDEM)
echo ${!tab[@]} # -> 0 1 2
echo ${tab[@]} # -> nouvelle valeur val2 val3
echo ${tab[0]} # -> nouvelle valeur
echo ${tab[1]} # -> val2
echo ${tab[2]} # -> val3
echo "--------"
for i in ${!tab[@]}
do
echo "$i : ${tab[$i]}"
done
DĂ©bogage
# Pas d'outil specialise
# Astuces :
# - echo a tous les points cles
# - Utiliser la fonction de Stefano Falsetto (debecho) et activer mode debug
# - Filtrer les sorties grace a tree
# - Utiliser la variable LINENO qui prendra la valeur de la ligne du script
# - Tester si la variable est un nombre
# - Intercepter le signal EXIT avec trap pour afficher un message ĂȘrsonnaliser en cas d'arret du script
Options de bash
#!/bin/bash -x
# Pour modifier le comportement du script
# -n, -v, -x, ...
# Au niveau du shebang : #!/bin/bash -x
echo coucou
echo coucou
# Ou en cours d'execution : set -X ou set +X pour retablir
set +x
echo coucou
echo coucou
set -v
echo coucou
echo coucou
# Voir les nombreuses autres possibilites sur le net...