01-Scripts Shell
01-Scripts Shell
01-Scripts Shell
1.2. Shebang
Le shebang, représenté par #!, est un en-tête d'un fichier texte qui indique au système d'exploitation
que ce fichier n'est pas un fichier binaire mais un script (ensemble de commandes) ; sur la même
ligne est précisé l'interpréteur permettant d'exécuter ce script. Pour indiquer au système qu’il s’agit
d’un script qui sera interprété par bash on placera le shebang sur la première ligne :
#!/bin/bash
#!/bin/bash
# script0.sh
echo "Hello World"
exit
Certaines variables ont une signification spéciale réservée. Ces variables sont très utilisées lors la
création de scripts : * pour récupérer les paramètres transmis sur la ligne de commande, * pour
savoir si une commande a échoué ou réussi, * pour automatiser le traitement de tous paramètres.
Par exemple :
#!/bin/bash
# script1.sh
echo "Nom du script $0"
echo "premier paramètre $1"
echo "second paramètre $2"
echo "PID du shell " \$\$
echo "code de retour $?"
exit
Donner les droits d’exécution au script :
chmod +ux script1.sh
Exécuter le script avec deux paramètres :
./script1.sh 10 zozo
En début de script, on peut définir la valeur de départ des variables utilisées dans le script.
VARIABLE="valeur"
Elles s'appellent comme ceci dans le script :
echo $VARIABLE
Il peut être utile de marquer les limites d'une variable avec les accolades.
echo ${VARIABLE}
Par exemple :
#!/bin/bash
# script2.sh
PRENOM="francois"
echo "dossier personnel /home/$PRENOM"
exit
1.7. Fonctions
if condition; then
commande1
else
commande2
fi
2.2. Tests
La condition pourra contenir un test. Deux manières de réaliser un test (avec une préférence pour la
première) :
[ expression ]
ou
test expression
Il y a beaucoup d’opérateurs disponibles pour réaliser des tests sur les fichiers, sur du texte ou sur
des valeurs (arithmétique).
Ces opérateurs de tests disponibles sont, pour les chaînes :
• [ -e $FILE ] : vrai si l'objet désigné par $FILE existe dans le répertoire courant,
• [ -s $FILE ] : vrai si l'objet désigné par $FILE existe dans le répertoire courant et si sa taille est
supérieure à zéro,
• [ -f $FILE ] : vrai si l'objet désigné par $FILE est un fichier dans le répertoire courant,
• [ -r $FILE ] : vrai si l'objet désigné par $FILE est un fichier lisible dans le répertoire courant,
• [ -w $FILE ] : vrai si l'objet désigné par $FILE est un fichier inscriptible dans le répertoire courant,
• [ -x $FILE ] : vrai si l'objet désigné par $FILE est un fichier exécutable dans le répertoire courant,
• [ -d $FILE ] : vrai si l'objet désigné par $FILE est un répertoire dans le répertoire courant,
• [ -N $FILE ] : vrai si l'objet désigné par $FILE à été modifié depuis la dernière lecture.
Par exemple :
#!/bin/bash
# script4.sh test si $passwdir existe
passwdir=/etc/passwdd
checkdir() {
if [ -e $passwdir ]; then
echo "le fichier $passwdir existe"
else
echo "le fichier $passwdir n'existe pas"
fi
}
checkdir
exit
Variante : script4a.sh
On reprend la fonction checkdir qui lit la valeur variable donnée par l’utilisateur :
#!/bin/bash
# script4a.sh test si $passwdir existe
read -p "quel est le dossier à vérifier ?" passwdir
checkdir() {
if [ -e $passwdir ]; then
echo "le fichier $passwdir existe"
else
echo "le fichier $passwdir n'existe pas"
fi
}
checkdir
exit
2.3. Structure de base d'un script
Shebang
Commentaire
Fonction gestion de la syntaxe
Fonction utile
Fonction principale
Fin
#!/bin/bash
# script5.sh structure de base d’un script
target=$1
usage() {
echo "Usage: $0 <fichier/dossier>"
exit
}
main() {
ls -l $target
echo "nombre de lignes : $(wc -l $target)"
stat $target
}
if [ $# -lt 1 ]; then
usage
elif [ $# -eq 1 ]; then
main
else
usage
fi
exit
2.4. Autres exemples de test
La page man de test pourrait nous inspirer.
execverif() {
if [ -x $target ] ; then
#('x' comme "e_x_ecutable")
echo $target " est exécutable."
else
echo $target " n'est pas exécutable."
fi
}
#! /bin/sh
# 01_tmp.sh
dir="${HOME}/tmp/"
if [ -d ${dir} ] ; then
rm -rf ${dir}
echo "Le dossier de travail ${dir} existe et il est effacé"
fi
mkdir ${dir}
echo "Le dossier de travail ${dir} est créé"
3. Boucles
3.1. Boucle for-do
Faire la même chose pour tous les éléments d'une liste. En programmation, on est souvent amené à
faire la même chose pour tous les éléments d'une liste. Dans un shell script, il est bien évidemment
possible de ne pas réécrire dix fois la même chose. On dira que l'on fait une boucle. Dans la boucle
for-do, la variable prendra successivement les valeurs dans la liste et les commandes seront répétées
pour chacune de ces valeurs.
for variable in liste_de_valeur; do
commande
commande
done
Par défaut, for utilise la liste in "$@" si on omet ce mot-clé.
Supposons que nous souhaitions créer 10 fichiers .tar.gz factices, en une seule ligne :
for num in 0 1 2 3 4 5 6 7 8 9; do touch fichier$num.tar.gz; done
Supposons que nous souhaitions renommer tous nos fichiers *.tar.gz en *.tar.gz.old :
#!/bin/bash
# script6.sh boucle
#x prend chacune des valeurs possibles correspondant au motif : *.tar.gz
for x in ./*.tar.gz ; do
# tous les fichiers $x sont renommés $x.old
echo "$x -> $x.old"
mv "$x" "$x.old"
#on finit notre boucle
done
exit
Script inverse
Voici le script inverse, c’est sans compter sur d’autres outils pour d’autres situations :
#!/bin/sh
# script6r.sh inverse
#x prend chacune des valeurs possibles correspondant au motif : *.tar.gz.old
for x in ./*.tar.gz.old ; do
# tous les fichiers $x sont renommés $x sans le .old
echo "$x -> ${x%.old}"
mv $x ${x%.old}
# on finit notre boucle
done
exit
3.2. Boucle while
Faire une même chose tant qu'une certaine condition est remplie. Pour faire une certaine chose tant
qu'une condition est remplie, on utilise une boucle de type while-do et until-do.
while condition do
commandes
done
Répète les commandes tant que la condition est vérifiée.
until condition do
commandes
done
Répète les commandes jusqu'à ce que la condition soit vraie soit tant qu'elle est fausse.
Rupture avec break,
Reprise avec continue.
while true; do commandes; done
Supposons, par exemple que vous souhaitiez afficher les 100 premiers nombres (pour une obscure
raison) ou que vous vouliez créer 100 machines virtuelles.
#!/bin/bash
# script7.sh boucle while
i=0
while [ $i -lt 100 ] ; do
echo $i
i=$[$i+1]
done
exit
De manière plus élégante avec l’instruction for :
#!/bin/bash
# for ((initial;condition;action))
for ((i=0;i<100;i=i+1)); do
echo $i
done
exit
\ Antislash
L'antislash \, qu'on appelle le caractère d'échappement, annule le sens de tous les caractères
génériques, en forçant le shell à les interpréter littéralement.
$ echo \$var
$var
$ echo "\$var"
$var
" " Guillemets
Les guillemets (doubles) " " sont les guillemets faibles mais annulent la plupart des méta-caractères
entourés à l'exception du tube (|), de l'antislash (\) et des variables ($var).
$ var=5
$ echo la valeur de la variable est $var
la valeur de la variable est 5
$ echo "la valeur de la variable est $var"
la valeur de la variable est 5
' ' Apostrophes
Les guillemets simples, ou apostrophes (' ') annulent le sens de tous les caractères génériques sauf
l'antislash.
$ echo '\$var'
\$var
Variables d’environnement
Des variables d’environnement sont disponibles dans toutes les sessions. Par exemple PATH indique
les chemins des exécutables :
$ echo $PATH
* /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
Pour afficher les variables d’environnement :
$ printenv
#! /bin/sh
# 06_affiche_arguments.sh
echo 0 : $0
if [ -n "$1" ] ; then echo 1 : $1 ; fi
if [ -n "$2" ] ; then echo 2 : $2 ; fi
if [ -n "$3" ] ; then echo 3 : $3 ; fi
if [ -n "$4" ] ; then echo 4 : $4 ; fi
if [ -n "$5" ] ; then echo 5 : $5 ; fi
if [ -n "$6" ] ; then echo 6 : $6 ; fi
if [ -n "$7" ] ; then echo 7 : $7 ; fi
if [ -n "$8" ] ; then echo 8 : $8 ; fi
if [ -n "$9" ] ; then echo 9 : $9 ; fi
if [ -n "${10}" ] ; then echo 10 : ${10} ; fi
On obtient ceci :
0 : ./06_affiche_arguments.sh
1 : un
2 : deux
3 : trois
4 : quatre
5 : zozo
6 : petzouille
7 : sept
8 : huit
9 : neuf
10 : 10
On peut optimiser les opérations avec la commande shift qui décale les paramètres vers la gauche
(supprime le premier paramètre) :
#! /bin/sh
# 07_affiche_arguments_3.sh
while [ -n "$1" ] ; do
echo $1
shift
done
$#représente le nombre total de paramètres. On peut voir ceci :
#! /bin/sh
# 08_affiche_arguments_4.sh
while [ $# -ne 0 ]; do
echo $1
shift
done
On peut encore illustrer d'autres paramètres positionnels :
#!/bin/bash
# 09_affiche_arguments_spéciaux.sh
echo "Nom du script $0"
echo "Sremier paramètre $1"
echo "Second paramètre $2"
echo "Tous les paramètres $*"
echo "Tous les paramètres (préservant des espaces) $@"
echo "Nombre de paramètres $#"
echo "PID du shell $$"
echo "code de retour $?"
exit