Scripts shell
Les scripts shell sont des suites de commandes, exécutées par séquences. L’écriture et l’exécution des scripts shell se fait en plusieurs étapes :
Étape 1: Ouvir le fichier dans un éditeur (par exemple « vi » ou « pico ».).
vi PremierScriptShell.sh
Étape 2: Tous les scripts shell doivent commencer par « #!/bin/bash » ou n’importe quel autre shell vous préférez. Cette ligne est appelée shebang, et même si elle ressemble à un commentaire elle n’en est pas un : elle indique au shell de l’interpéteur que le fichier est un script. Le chemin fourni doit être absolu (on ne peut, par exemple, pas utiliser « bash »). Le shebang doit être en première ligne du script, sans espace qui le précède.
Étape 3: Écrire le code que vous voulez développer. Notre premier script shell , que nous placerons dans le fichier « PremierScriptShell.sh », affichera l’habituel « Hello World »..
#!/bin/sh echo "Hello World"
Étape 4: La prochaine étape est de rendre le script exécutable en utilisant la commande « chmod ».
chmod 744 PremierScriptShell.sh
ou
chmod +x PremierScriptShell.sh
Étape 5: Exécuter le script. Elle peut être faite en entrant le nom du script dans la ligne de commande, précédée par son chemin. S’il est dans le répertoire courant, c’est très simple :
bash$ ./PremierScriptShell.sh Hello World
Si vous voulez voir l’exécution étape par étape (ce qui peut être très utile en cas de bug), il faut lancer le script en ajoutant l’option « -x » :
sh -x PremierScriptShell.sh + echo 'Hello World' Hello World
Pour voir le contenu d’un script, vous pouvez utilisez la commande « cat » ou encore l’ouvrir dans n’importe quel éditeur de texte:
bash$ cat PremierScriptShell.sh #!/bin/sh echo Hello World
Les commentaires dans le shell
Dans les scripts shell, toutes les lignes commençant par # sont des commentaires.
# Ceci est une ligne de commentaire. # Ceci en est une autre.
Il peut aussi y avoir des commentaires sur plusieurs lignes, pour cela il suffit d’utiliser « : » suivi d’une apostrophe :
: 'Ceci est un ligne de commentaire. Encore une ! Et celle ci aussi en est une ! '
Remarque : Cette méthode ne fonctionnera pas s’il y a une apostrophe dans les lignes de commentaires.
Variables
Comme vous devez le savoir, ou pas, les variables sont la partie la plus significative de n’importe quel langage, que ce soit Perl, C ou les scripts shell. Dans le shell, les variables sont classées en deux types : les variables système et les variables définies par l’utilisateur.
Variables système
Les variables système sont définies et enregistrées dans l’environnement du shell parent (le shell à partir duquel le script est exécuté). Ces variables sont aussi appelées variables d’environnement. Elles sont écrites en lettres capitales et peuvent être affichées en utilisant la commande « set ». Voici quelques exemples de variables système : PWD, HOME, USER, etc. Leurs valeurs peuvent être affichées individuellement en utilisant la commande « echo ». Par exemple, echo $HOME
nous permettra de voir la valeur stockées dans la variable système HOMME.
Pour mettre à jour ou créer une variable système, il faut utiliser la commande « export » pour la rendre accessible aux shell fils (les shell lancés à partir du shell courant, y compris les scripts):
bash$ SCRIPT_PATH=/home/blessen/scriptshell bash$ export SCRIPT_PATH
Les shells modernes permettent de faire ceci en en ligne de commande :
bash$ export SCRIPT_PATH=/home/blessen/scriptshell
Variables utilisateurs
Ce sont les variables utilisées habituellement dans les scripts, celles qui ne sont pas rendues accessibles à d’autres programmes. Leurs noms ne peuvent pas commencer par un chiffre et sont écrites en lettres minuscules avec des tirets bas. Par exemple : « def_vartemp ».
Pour assigner une valeur à une variable, il faut écrire le nom de la variable suivi de « = » et la valeur (par exemple : "def_valtemp=blessen"
). Il ne doit y avoir aucun espace autour du signe égal. Pour utiliser ou afficher la variable, il faut utiliser la commande « echo » et précéder la variable du signe « $ » :
bash$ echo $def_valtemp blessen
Le script qui suit définit la variable « username » et affiche sont contenu quand il est exécuté.
#!/bin/sh username=blessen echo "Le nom d'utilisateur est $username"
Les arguments en ligne de commande
Ce sont des variables contenant les arguments d’un script quand il est exécuté. Ces variables sont accessibles avec $1, $2,…,$n, avec $1 le premier argument passé en ligne de commande, $2 le second, etc. Les arguments sont séparés par des espaces. $0 est le nom du script. La variable $# affiche le nombre d’arguments fournis, ce nombre est limité à 9 dans les anciens shell et est pratiquement illimité dans ceux modernes.
Considérons un script qui prends deux arguments et les affiche. Nous l’appelerons « lignecommande.sh ».
#!/bin/sh echo "La première variable est $1" echo "La seconde variable est $2"
Quand j’exécute « lignecommande.sh » avec des arguments comme « blessen » et ‘lijoe », le résultat est :
bash$ ./lignecommande.sh blessen lijoe La première variable est blessen La seconde variable est lijoe
Variable de statut de fin
Cette variable permet de savoir si la dernière commande exécutée a réussi ou non. Elle est représentée par $?. Une valeur de 0 signifie que la commande a été exécutée avec succès, tout autre nombre indique qu’il y a eu échec (certains programmes, comme mail, renvoient cependant d’autres chiffres que 0 pour indiquer le statut plutôt qu’un échec). C’est très utile pour les scripts.
Pour tester cela, créez un fichier « test » en exécutant touch test
. Puis affichez le contenu du fichier.
bash$ cat test
Vérifiez la valeur de $?.
bash$ echo $? 0
La valeur est 0 car la commande a été exécutée avec succès. Essayez maintenant de lancer « cat » sur un fichier qui n’existe pas :
bash$ cat xyz1 bash$ echo $? 1
La valeur 1 montre que la commande ci-dessus a échoué.
La portée d’une variable
Je suis sûr que la plupart des programmeurs ont appris (et sûrement travaillé avec) les variables et le concepte de portée
(c’est une définition du contexte dans lequel la variable est définie). Dans la programmation shell, on utilise aussi la portée d’une variable pour plusieurs tâches, même si c’est rarement nécessaire, cela peut être un outils utile. Dans le shell, il y a deux types de portée : globale et locale. Les variables locales sont définies en utilisant le mot clef « local » avant le nom de la variable lors de sa définition ; toutes les autres variables, sauf celles associées aux arguments des fonctions, sont globales et donc accessibles partout dans le script. Le script ci-dessous montre les différentes portées d’une variable locale et d’une autre globale :
#!/bin/sh affiche() { local local_var=100 global_var=blessen echo "La variable locale est $local_var" echo "La variable globale est $global_var" } echo "======================" affiche echo "======= dehors ========" echo "La variable locale en dehors de la fonction est $local_var" echo "La variable globale en dehors de la fonction est $global_var"
L’exécution du script donne :
====================== La variable locale est 100 La variable globale est blessen =======outside ======== La variable locale en dehors de la fonction est La variable globale en dehors de la fonction est blessen
Notez l’absence de valeur pour la variable locale en dehors de la fonction.
Entrée et sortie dans les scripts shell
Pour accepter les entrées avec le clavier, on utilise read
. Cette commande va lire les valeurs entrées sur le clavier et les assigner à chaque variable spécifiées.
read <variable_name>
Pour les sorties, on utilise la commande echo
.
echo "phrase à afficher"
Les opération arithmétiques dans les scripts shell
Comme les autres langages de scripts, le shell permet aussi d’utiliser les opérations arithmétiques telles que l’addition, la soustraction, la multiplication et la division. Pour les utiliser, il faut faire appel à la fonction expr
. Par exemple « expr a + b » signifie « ajouter a et b ».
Exemple :
somme=`expr 12 + 20`
La syntaxe est similaire pour les opération de soustraction, division et multiplication. Il y a un autre moyen de faire des opérations arithmétiques ; entourer les variables et l’équation par des crochets précédés d’un signe $ :
$[expression operation instruction]
Exemple :
echo $[12 + 10]
[Notez que cette syntaxe n’est pas universelle, elle échouera par exemple dans le shell Korn. La syntaxe ‘$((…))’ est plus adaptée, indifféremment du shell ; cependant il vaut mieux, sur le principe général de « laisser le shell faire ce qu’il fait de mieux et laisser le reste aux outils standards », utiliser un programme de calcul comme « bc » ou « dc » et la substitution de commande. Aussi, notez que l’arithmétique en shell se faire sur les entiers uniquement, alors que les deux méthodes ci-dessus n’ont pas ce problème. — Ben]
Les instructions conditionnelles
Amusons-nous un peu avec une instruction conditionnelle comme « if condition ». La plupart du temps, nous programmeurs shell, nous retrouvons dans des situations où nous devons comparer deux variables, et après exécuter certaines instructions dépendant de la véracité de la condition. Donc, dans de tels cas, on utilise l’instruction « if ». La syntaxe est la suivante :
if [ instruction conditionnelle ] then ... instructions ... fi
Le script ci-dessous va demander le nom d’utilisateur, et si celui ci est « blessen », va afficher un message montrant que la connexion a réussi. Sinon, il affichera « mauvais nom d’utilisateur ».
#!/bin/sh echo "Entrer votre nom d'utilisateur:" read username if [ "$username" = "blessen" ] then echo 'Bravo, vous êtes connecté.' else echo 'Désolée mauvais nom d'utilisateur.' fi
Rappelez vous de toujours écrire la variable à tester entre guillemets ; si vous ne le faites pas, le script échouera à cause de la mauvaise syntaxe quand la variable est vide. Aussi, les crochets (qui sont un alias pour la commande test) doivent être entourés d’espaces.
Comparaison de variables
Nous pouvons être amenés à comparer des variables. Si la valeur d’une variable à comparer est numérique, il faut utiliser ces options :
-eq Égal à
-ne Différent de
-lt Inférieur à
-le Inférieur ou égal à
-gt Supérieur à
-ge Supérieur ou égal à
Si ce sont des chaînes de caractères, il faut utiliser les options suivantes :
= Égal )
!= Différent de
< La premièe chaîne de caractère arrive avant la 2e dans l’ordre alphabétique
> La premièe chaîne de caractère arrive après la 2e dans l’ordre alphabétique
Les boucles
La boucle « for »
La boucle la plus utilisée est la boucle « for ». Dans les scripts shell, il y en a deux types : une similaires à celle du langage C, et une boucle avec itérateur (utilisant des listes).
Syntaxe pour le premier typ de boucle « for » (utilisable seulement dans les shell modernes):
for ((initialisation; condition; incrémentation/décrémentation)) do ...instructions... done
Exemple:
#!/bin/sh for (( i=1; $i <= 10; i++ )) do echo $i done
Cela va produire une liste de nombre de 1 à 10. La syntaxe pour la seconde boucle for, utilisable dans plus de shell :
for <variable> in <liste> do ...instructions... done
Ce script va lire le contenu de « /etc/group » et afficher une ligne à la fois :
#!/bin/sh compteur=0 for i in `cat /etc/group` do compteur=`expr "$compteur" + 1` echo "La ligne $compteur est affichée" echo $i done echo "Fin du fichier"
Un autre exemple de la boucle « for » utilise « seq » pour générer une séquence :
#!/bin/sh for i in `seq 1 5` do echo $i done
La boucle while
La boucle « while » est une autre boucle utile dans tous les langages de programmation; elle s’exécute jusqu’à ce que la condition spécifiée devienne fausse.
while [ condition ] do ...instruction... done
Le scripte suivant assigne la valeur 1 à la variable num
et ajoute 1 à la valeur num
à chaque itération de la boucle, tant que la valeur de num
est inférieure à 5.
#!/bin/sh num=1 while [$num -lt 5]; do num=$[$num + 1]; echo $num; done
Les instructions select et case
Similaire à la structure « switch/case » en C, la combinaison de « select » et « case » permet aux programmeurs shell d’utiliser les mêmes fonctionnalités. L’instruction « case » ne fait pas partie de « case », mais j’ai assemblé les deux pour illustrer leur utilisateur en programmation.
Syntaxe de select:
select <variable> in <liste> do ...instructions... done
Syntaxe de case:
case $<variable> in <option1>) instructions ;; <option2>) instructions ;; *) echo "Désolé, mauvaise option" ;; esac
L’exemple ci-dessous expliquera l’utilisation de select et case ensemble, et affichera les options impliquant la nécessité de redémarrer un composant de la machine. Quand l’utilisateur sélectionne une option, le script lance le service correspondant.
#!/bin/bash echo "***********************" select opt in apache named sendmail do case $opt in apache) /etc/rc.d/init.d/httpd redémarrer;; named) /etc/rc.d/init.d/named redémarrer;; sendmail) /etc/rc.d/init.d/sendmail redémarrer;; *) echo "Rien ne sera redémarré" esac echo "***********************" #Si le break ne figure pas ici, il n'y aura pas d'invite de commande break done
[Au lieu d’utiliser une instruction « break » explicite, qui n’est pas utile si vous voulez utiliser plus d’une des options présentées, il est beaucoup mieux d’inclure « Quit » comme dernière option dans la liste de select, avec une instruction y correspondant. — Ben ]
Fonctions
Dans le monde moderne où les tous programmeurs utilisent le modèle OOP pour programmer, même nous, programmeurs shell ne sommes pas loin derrière. Nous pouvons aussi diviser le code en plusieurs parties appelée fonctions, et leur donner un nom dans le programme principal. Cette approche aide pour débugger et réutiliser le code, etc.
La syntaxe pour les fonctions est :
<nom de la fonction> () { # début de la fonction instructions } # fin de la fonction
Les fonctions sont appelées en utilisant leurs noms dans le programme principal, suivi éventuellement par des arguments. Par exemple :
#!/bin/sh sumcalc () { sum=$[$1 + $2] } echo "Entrer le premier nombre:" read num1 echo "Entrer le second nombre:" read num2 sumcalc $num1 $num2 echo "Résultat pour sumcalc: $sum"
Debugger les scripts shell
Parfois, on a besoin de débugger un programme. Pour ce faire, on utilise les options « -x » et « -v » du shell. L’option « -v » produit une longue sortie. L’option « -x » étendra chaque commande simple, la commande « for », la commande « case », la commande « select » , ou la commande arithmétique « for », afichant la valeur étendue de PS4, suivi par la commande et ses arguments étendus ou mots associés. Essayez les dans cet ordre, ils peuvent être très utiles quand vous n’arrivez pas à localiser le problème dans votre script.
https://doc.ubuntu-fr.org/tutoriel/script_shell