Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
tutoriel:script_shell [Le 12/02/2024, 14:20] – ancienne révision (Le 19/09/2023, 14:21) restaurée pour vandalisme 81.247.240.195tutoriel:script_shell [Le 28/07/2026, 10:51] (Version actuelle) – [Liens] ajout lien vers blog S.Robert ! bcag2
Ligne 5: Ligne 5:
 ====== Introduction aux scripts shell ====== ====== Introduction aux scripts shell ======
  
-Un script shell permet d'automatiser une série d'opérations. Il se présente sous la forme d'un fichier contenant une ou plusieurs commandes qui  seront exécutées de manière séquentielle. Fantastique.+Un script shell permet d'automatiser une série d'opérations. Il se présente sous la forme d'un fichier contenant une ou plusieurs commandes qui  seront exécutées de manière séquentielle.
 <code bash> <code bash>
 #!/bin/bash #!/bin/bash
Ligne 56: Ligne 56:
 ==== Méthode dans un terminal ==== ==== Méthode dans un terminal ====
  
-Il suffit de se placer dans le dossier où est le script, et de lancer : <code bash>bash nom_du_script</code> +Pour  utiliser un script, on peut le lancer avec la commande servant à l'interpréter. Pour utiliser l'[[#Les différents types de shells|interpréteur]] [[:bash]] (par défaut sur Ubuntu), ce sera la commande ''[[man>bash]]''
-mais pas toujours bash ( dépend du langage du script )+<code bash>bash /chemin/du/script.sh</code>
  
-ou si vous voulez l'exécuter par son  nom , il faut le rendre exécutable avec ''chmod''Pour ceci tapez la commande qui suit : <code bash>chmod +x nom_du_script</code>+La commande est à adapter selon l'application et selon le [[:chemins|chemin]] du scriptSi le script se trouve dans le [[:chemins#chemin_relatif|répertoire courant]], on peut se contenter de la commande : 
 +<code bash>bash script.sh</code>
  
-Puis vous pouvez exécuter le script en faisant : <code bash>./nom_du_script</code> +Grâce au [[#shebang]], on peut aussi interpréter un script simplement en l'appelant par son nom.\\ 
-mais pourquoi le ./ ?+Il faut avant tout le rendre exécutable avec ''chmod'' (voir //[[:Permissions]]//).\\ 
 +Pour ceci entrer la commande : 
 +<code bash>chmod +x script.sh</code> 
 + 
 +Puis exécuter le script avec : 
 +<code bash>./script.sh</code>
  
 === Le chemin ./ === === Le chemin ./ ===
  
-Il peut être intéressant d'ajouter un répertoire au "PATH" pour pouvoir exécuter ses scripts sans avoir à se placer dans le bon dossier. +Ce ''./'' dépend du [[:chemins|chemin]] du script : ''./'' signifie "[[:chemins#chemin_relatif|répertoire courant]]et permet au système d'appeler un script hors ''[[#$PATH]]''.
-Je m'explique, quand vous tapez une commande ("lspar exemple), le shell regarde dans le PATH qui lui indique où chercher le code de la commande.+
  
-Pour voir à quoi ressemble votre PATH, tapez dans votre console:+=== $PATH === 
 + 
 +La [[:variables_d_environnement|variable d'environnement]] ''[[:variables_d_environnement#variables_liees_aux_emplacements_de_fichiers|$PATH]]'' définit les répertoires où le système doit chercher les fichiers exécutables. 
 + 
 +En plaçant un fichier exécutable (comme un script) dans l'un de ces répertoires, il n'est pas nécessaire de spécifier son [[:chemins|chemin]] complet pour le lancer. Le nom du fichier suffit.\\ 
 +Ubuntu dispose d'un répertoire des [[:arborescence#binaires personnels]] à cet effet dans le [[:arborescence#répertoire personnel]] de chaque [[:utilisateur]], qu'on peut manipuler sans les [[:permissions administrateur]]. 
 + 
 +Pour voir à quoi ressemble ''$PATH''entrer la commande :
   echo $PATH   echo $PATH
  
-Cette commande chez moi donnait initialement :+Cette commande retourne par exemple :
   /usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games   /usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
  
-C'est à dire que le shell va aller voir si la définition de la commande tapée ("ls" pour continuer sur le même exemple) se trouve dans **/usr/local/bin** puis dans **/usr/bin**... jusqu'à ce qu'il la trouve.+C'est à dire que le système va aller voir si un script ou un exécutable se trouve dans ''/usr/local/bin'', puis dans ''/usr/bin'', puis dans ''/bin'', etc.
  
-Ajouter un répertoire au PATH peut donc être très pratique. Par convention, ce répertoire s'appelle **bin** et se place dans votre répertoire personnel. Si votre répertoire personnel est /home/toto, ce répertoire sera donc **/home/toto/bin**. +On peut aussi ajouter un répertoire particulier à la variable ''$PATH''.\\ 
-Pour pouvoir utiliser vos scripts en tapant directement leur nom (sans le "./") depuis n'importe quel répertoire de votre ordinateur, il vous suffit d'indiquer au shell de chercher aussi dans ce nouveau dossier en l'ajoutant au PATH+Pour ceci, il suffit d'entrer :
-Pour ceci, il suffit de faire :+
   export PATH=$PATH:$HOME/bin   export PATH=$PATH:$HOME/bin
 +où ''$HOME/bin'' est le répertoire concerné.
  
 La commande La commande
Ligne 87: Ligne 99:
   /usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/toto/bin   /usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/toto/bin
  
-et je peux lancer le script appelé "monScriptsitué dans "/home/toto/binen tapant directement :  monScript+et on peut lancer le script appelé ''monScript.sh'' situé dans ''/home/toto/bin'' en entrant directement :  
 +  monScript.sh
  
-<note tip>Cette procédure est pour une modification temporaire du PATH et qui sera donc effacée à la fin de la session. Pour rendre la modification permanente, ajouter la commande dans le fichier texte caché .bashrc se trouvant dans votre dossier personnel ainsi que dans le dossier /root.</note>+<note tip> 
 +Cette modification du ''$PATH'' est seulement temporaire et sera effacée à la fin de la [[:session utilisateur|session]].\\ 
 +Pour rendre la modification permanente, ajouter cette commande dans le fichier caché ''~/.bashrc'' se trouvant dans le [[:arborescence#répertoire personnel]]. 
 +</note>
  
-<note important>Dans les dernières versions de ubuntu (12.04 +) si le dossier $HOME/bin existe il est automatiquement ajouté au PATH. La commande est incluse dans le fichier ~/.profile lancé lors de toutes sessions (graphique ou console).</note>+<note important> 
 +En l'occurrence si le répertoire ''$HOME/bin'' existe il est automatiquement ajouté au ''$PATH''. La commande est incluse dans le fichier ''~/.profile'' lancé lors de toutes sessions (graphique ou console). 
 +</note>
  
 === Les différents types de shells === === Les différents types de shells ===
  
-Comme vous avez sûrement dû l'entendre, il existe différents types de shells ou en bon français, interpréteurs de commandes :+Il existe différents types de //shells//ou interpréteurs de commandes : 
 + 
 +  * ''[[wpfr>Debian_Almquist_shell|dash]]'' (//Debian Almquist shell//) : //shell// plus léger que bash, installé par défaut sur Ubuntu 
 +  * ''[[:bash]]'' (//Bourne Again SHell//) : conçu par le projet GNU, shell linux ; le //shell// par défaut sur Ubuntu 
 +  * ''rbash'' : un //shell// restreint basé sur ''bash''. Il existe de nombreuses variantes de ''bash'' 
 +  * ''csh'', ''tcsh'' : //shell// C, créés par Bill Joy de Berkeley 
 +  * ''zsh'', //shell// C écrit par Paul Falstad 
 +  * ''ksh'' : //shell// korn écrits par David Korn((''pdksh'' Public Domain Korn Shell <=> ksh88 sur Solaris et équivaut à ksh93 sur les autres UNIX/Linux cf.[[wp>Korn_shell#History|Korn shell History]])) 
 +  * ''rc'' : //shell// C, lui aussi conçu par le projet GNU 
 +  * ''tclsh'' : //shell// utilisant Tcl 
 +  * ''wish'' : //shell// utilisant Tk 
 + 
 +Il existe encore beaucoup d'autres types de //shells//.\\ Pour savoir quel type de //shell// est utilisé sur une machine, entrer la commande ''[[man>ps]]''
 + 
 +La commande ''[[man>sh]]'' est en fait un [[:lien_physique_et_symbolique|lien symbolique]] vers l'interpréteur de commandes par défaut : ''/usr/bin/dash''
 + 
 +<note> 
 +On  peut aussi écrire des scripts dans d'autres langages interprétés : 
 +  * ''[[:python]]'' 
 +  * ''[[:php]]'' 
 +  * ''[[:nodejs|node]]'' pour [[wpfr>JavaScript]] 
 +  * ''[[wpfr>Perl_(langage)|perl]]'' 
 +  * etc. 
 +</note>
  
-  * [[wpfr>Debian_Almquist_shell|dash]] (//Debian Almquist shell//) : shell plus léger que bash, installé par défaut sur Ubuntu ; +=== Shebang ===
-  * [[:bash]] (//Bourne Again SHell//) : conçu par le projet GNU, shell linux ; le shell par défaut sur Ubuntu ; +
-  * rbash : un shell restreint basé sur bash. Il existe de nombreuses variantes de bash ; +
-  * csh, tcsh : shells C, créés par Bill Joy de Berkeley ; +
-  * zsh, shell C écrit par Paul Falstad ; +
-  * ksh (<=> ksh88 sur Solaris et équivaut à ksh93 sur les autres UNIX/Linux cf.[[http://en.wikipedia.org/wiki/Korn_shell#History|Korn shell History]]): shells korn écrits par David Korn, pdksh (Public Domain Korn Shell <=> ksh88) ; +
-  * rc : shell C, lui aussi conçu par le projet GNU ; +
-  * tclsh : shell utilisant Tcl ; +
-  * wish : shell utilisant Tk .+
  
-Il existe bien entendu beaucoup d'autres types de shells.\\ Pour savoir quel type de shell est présent sur une machine, aller dans un terminal et taper la commande **ps**.+Le [[wpfr>shebang]] est la déclaration en commentaire à la première ligne du script qui informe le système du chemin de l'interpréteur à utiliser, précédé des caractères ''#!''.
  
-La commande **sh** est en fait un lien symbolique vers l'interpréteur de commandes par défaut **/bin/dash**.+Pour ''[[man>bash]]'' il sera de la forme : 
 +<file>#!/bin/bash</file>
  
 ===== Les variables ===== ===== Les variables =====
-Il faut savoir que en bash les variables sont toutes des chaînes de caractères.\\+Il faut savoir qu'en bash les variables sont toutes des chaînes de caractères.\\
 Cela dépendra de son USAGE, pour une opération arithmétique prochaine voir : let ma_variable sinon pour conserver une valeur : Cela dépendra de son USAGE, pour une opération arithmétique prochaine voir : let ma_variable sinon pour conserver une valeur :
 il suffit de lui donner un nom et une valeur avec l'affectation égale : il suffit de lui donner un nom et une valeur avec l'affectation égale :
Ligne 252: Ligne 286:
     echo "Bien joué !"     echo "Bien joué !"
   else   else
-    echo "Non mais quand même !!! SAPERLIPOPETTE C'ÉTAIT $1 ET NON PAS $Reslt ESPECE DE NOUILLE !!!" +    echo "Non mais quand même !!! C'ÉTAIT $1 ET NON PAS $Reslt PETIT FRIPON !!!" 
-    sleep 3 # Juste pour le fun du script qui enrage ;-p +    sleep 3 # Juste pour le fun du script qui rage ;-p 
-    echo "Désolé, je te bannis de ubuntu-fr.org ! Et schbim !! Dommage tu ne peux rien contre moi !!!"+    echo "Donc je te bannis de ubuntu-fr.org ! Et toc !! Tu ne peux rien contre moi !!!"
     exit 1     exit 1
   fi   fi
Ligne 266: Ligne 300:
 Exemple: besoin de définir des plages de valeurs (1 à 500 puis 501 à 1000 puis 1001 à 1500…) Exemple: besoin de définir des plages de valeurs (1 à 500 puis 501 à 1000 puis 1001 à 1500…)
 <code bash> <code bash>
-id_per_step = 500+id_per_step=500
 for (( i=0; i<8; i++ )); do for (( i=0; i<8; i++ )); do
  (( min_step_id = 1 + $i * $id_per_step ))  (( min_step_id = 1 + $i * $id_per_step ))
Ligne 284: Ligne 318:
  
 ^ Syntaxe ^ Fonction réalisée ^ ^ Syntaxe ^ Fonction réalisée ^
-| -e fichier      | renvoie 0 si fichier existe.                           | +| -e fichier (ou répertoire)      | renvoie 0 si fichier/répertoire existe.                           | 
-| -d fichier      | renvoie 0 si fichier existe et est un répertoire.      +| -d répertoire                 | renvoie 0 si fichier existe et est un répertoire.                 
-| -f fichier      | renvoie 0 si fichier existe et est un fichier 'normal'.| +| -f fichier                    | renvoie 0 si fichier existe et est un fichier (pas un répertoire).| 
-| -w fichier      | renvoie 0 si fichier existe et est en écriture.        +| -w fichier                    | renvoie 0 si fichier existe et est en écriture.                   
-| -x fichier      | renvoie 0 si fichier existe et est exécutable.         +| -x fichier                    | renvoie 0 si fichier existe et est exécutable.                    
-| f1 -nt f2       | renvoie 0 si f1 est plus récent que f2.                +| f1 -nt f2                     | renvoie 0 si f1 est plus récent que f2.                           
-| f1 -ot f2       | renvoie 0 si f1 est plus vieux que f2.                 |+| f1 -ot f2                     | renvoie 0 si f1 est plus vieux que f2.                            | 
 +<note tip>Si vous préférez vérifier que votre //fichier/répertoire// N’existe PAS, //-e// -> //! -e//</note>
  
 === Opérateurs de comparaison numérique === === Opérateurs de comparaison numérique ===
Ligne 323: Ligne 358:
  
 Il y a en 3 : Il y a en 3 :
-  * le **et** logique : -a +^ opérateur ^ solution POSIX ^ solution BASH moderne ^ 
-  le **ou** logique -o +**et** logique | **-a** avec simple crochets,\\ exemple <code>[ -n "$ma_var" -a "$ma_var" = "Oui" ]</code>\\ mais on peut aussi écrire :\\ <code>[ -n "$ma_var" ] &&  [ "$ma_var" = "Oui" ]</code>**&&** avec double crochets, exemple : <code bash>[[ -n "$ma_var" && "$ma_var" == "Oui" ]]</code>
-  le **non** logique : ! +**ou** logique | **-o** avec simple crochets | **||** avec double crochets\\ <code bash>[[ "$ma_var" = "Oui" || "$ma_var" = "Yes" ]]</code> 
-Exemple : +| **non** logique | **!** dans tous les cas | |
-<code bash> +
-echo "renverra 0 si les deux expressions sont vraies" +
-test expr1 -a expr2   +
-[ expr1 -a expr2 ] +
-</code>+
  
 == Table de vérité de « -a » == == Table de vérité de « -a » ==
Ligne 385: Ligne 415:
     ls -la     ls -la
 elif [ "$ouinon" = "n" ] || [ "$ouinon" = "N" ]; then elif [ "$ouinon" = "n" ] || [ "$ouinon" = "N" ]; then
-    echo "Ok, Aurevoir! "+    echo "Ok, bye! "
 else else
     echo "Il faut taper Y ou N!! Pas $ouinon"     echo "Il faut taper Y ou N!! Pas $ouinon"
 fi fi
 </code> </code>
 +<note tip>Simple ou double crochets ?(((EN) https://stackoverflow.com/questions/13542832/what-is-the-difference-between-single-and-double-square-brackets-in-bash et \\ (FR) https://blog.stephane-robert.info/docs/admin-serveurs/linux/exploiter/scripts/conditions-bash/#--vs---vs-))\\  
 +Les crochets simples [] correspondent à des tests de condition conformes au shell POSIX.\\  
 +Les doubles permettent d'avantage d'opérations dont les expressions rationelles ([[wpfr>Expression_régulière|REGEX]])\\  
 +Préférez les crochets simples pour une meilleure compatibilité. 
 +</note>
 === Explication === === Explication ===
  
Ligne 402: Ligne 436:
 L'instruction ''`read`'' permet d'affecter une valeur ou un caractère à une variable quelconque, en la demandant à l'utilisateur. L'instruction ''`read`'' permet d'affecter une valeur ou un caractère à une variable quelconque, en la demandant à l'utilisateur.
  
-<note>En bash, la variable est considérée comme une chaîne même si celle-ci contient une valeur numérique, et les majuscules sont considérées différentes des minuscules, $M ≠ $m.</note>+<note>En bash, la variable est considérée comme une chaîne même si celle-ci contient une valeur numérique,\\ et les majuscules sont considérées différentes des minuscules, $M ≠ $m.</note>
  
 Ensuite vient l'instruction conditionnelle `if`. Elle est suivie d'un « [ » Ensuite vient l'instruction conditionnelle `if`. Elle est suivie d'un « [ »
Ligne 413: Ligne 447:
  
 Exemple : Exemple :
-créer le répertoire titi s'il n' existe pas+créer le répertoire toto s'il n' existe pas
 <code bash> <code bash>
-[ ! -d /tmp/titi ] && mkdir /tmp/titi +[ ! -d /tmp/toto ] && mkdir /tmp/toto 
-[ -d /tmp/titi ] || mkdir /tmp/titi +[ -d /tmp/toto ] || mkdir /tmp/toto 
-test ! -d /tmp/titi && mkdir  /tmp/titi +test ! -d /tmp/toto && mkdir  /tmp/toto 
-rm -rf /tmp/titi;mkdir /tmp/titi+rm -rf /tmp/toto;mkdir /tmp/toto
 </code> </code>
  
Ligne 535: Ligne 569:
      
 case "$on" in case "$on" in
-    oui | o | O | Oui | OUI ) echo "Allez boire un Thé !";;+    oui | o | O | Oui | OUI ) echo "Allez faire du café !";;
     non | n | N | Non | NON ) echo "Programmez !";;     non | n | N | Non | NON ) echo "Programmez !";;
     * ) echo "Ah bon ?";;     * ) echo "Ah bon ?";;
Ligne 547: Ligne 581:
 <code bash> <code bash>
 case "$truc....." in case "$truc....." in
-    [nN] *) echo "Blablablabla...";;+    [nN] *) echo "Blablabla...";;
     n* | N* ) echo "Bla....";;     n* | N* ) echo "Bla....";;
 </code> </code>
Ligne 732: Ligne 766:
 #favoritefood #favoritefood
 if [ ${LANG:0:2} = "fr" ]; then if [ ${LANG:0:2} = "fr" ]; then
-    echo "Vous aimez la choucroute !"+    echo "Vous aimez les moules frites !"
 elif [ ${LANG:0:2} = "en" ]; then elif [ ${LANG:0:2} = "en" ]; then
-    echo "You love the... raclette !"+    echo "You love the... pudding !"
 elif [ ${LANG:0:2} = "es" ]; then elif [ ${LANG:0:2} = "es" ]; then
-    echo "Te gusta el pata negra !"    +    echo "Te gusta el jamón !"    
 else else
     echo ":'-("     echo ":'-("
Ligne 745: Ligne 779:
 <code bash> <code bash>
 $ ./favoritefood $ ./favoritefood
-Vous aimez la choucroute !+Vous aimez les moules frites !
 $ env LANG=en ./favoritefood $ env LANG=en ./favoritefood
-You love the... raclette!+You love the... pudding !
 $ env LANG=es ./favoritefood $ env LANG=es ./favoritefood
-Te gusta el pata negra!+Te gusta el jamón !
 $ env LANG=it ./favoritefood $ env LANG=it ./favoritefood
 :'-( :'-(
Ligne 826: Ligne 860:
  
 <code bash> <code bash>
-echo -e '\033[1;30;47m titi \033[0;32m est sur \033[1;33m un bateau \033[0m'+echo -e '\033[1;30;47m toto \033[0;32m est sur \033[1;33m un bateau \033[0m'
 </code> </code>
  
Ligne 877: Ligne 911:
 Exemple : Exemple :
 supposons que vous ayez une base de données, avec 3 catégories d'enregistrements possibles : supposons que vous ayez une base de données, avec 3 catégories d'enregistrements possibles :
-canard bleu, canard blanc, canard rose ayant chacun 30 individus.+éléphant bleu, éléphant blanc, éléphant rose ayant chacun 30 individus.
 Votre script doit compter le nombre d'éléphants bleus et blancs. Votre script doit compter le nombre d'éléphants bleus et blancs.
 Deux possibilités s'offrent à vous : Deux possibilités s'offrent à vous :
-  * calculer le nombre de canard verts canard violets+  * calculer le nombre d'éléphants bleus éléphants blancs
 ou ou
-  * calculer le nombre total de canard - nombre de canard roses+  * calculer le nombre total d'éléphants - nombre d'éléphants roses
  
 Quel algorithme choisissez-vous ? Quel algorithme choisissez-vous ?
  
-Résultat : le premier car dans le deuxième il faut d'abord calculer le nombre total de canard.+Résultat : le premier car dans le deuxième il faut d'abord calculer le nombre total d'éléphants, donc un calcul en plus :-P .
  
 ===== Liens ===== ===== Liens =====
  
-  * (fr) https://marcg.developpez.com/ksh/ Pour ceux qui souhaitent aller plus loin dans la conception de script shell.+  * (fr) [[https://blog.stephane-robert.info/docs/admin-serveurs/linux/exploiter/scripts/shell/|Très bon tuto de Stéphane Robert]] 
 +  * (fr) [[https://marcg.developpez.com/ksh/|Pour ceux qui souhaitent aller plus loin dans la conception de script shell, tuto de MarcG sur developpez.com]]
   * (fr) [[https://abs.traduc.org/abs-fr/|Guide avancé d'écriture des scripts Bash]] : Un très bon tutoriel concernant la réalisation du script shell. C'est l'un des plus complets et les mieux détaillés disponibles en français. Il contient également [[http://abs.traduc.org/abs-5.3-fr/apa.html|des exemples de script complets]], une [[http://abs.traduc.org/abs-5.3-fr/apb.html|carte de référence]] (variables, tests...). Ce site est un site qui vaut réellement le détour pour tous ceux qui cherchent à créer des scripts complets en utilisant au mieux les performances du shell.   * (fr) [[https://abs.traduc.org/abs-fr/|Guide avancé d'écriture des scripts Bash]] : Un très bon tutoriel concernant la réalisation du script shell. C'est l'un des plus complets et les mieux détaillés disponibles en français. Il contient également [[http://abs.traduc.org/abs-5.3-fr/apa.html|des exemples de script complets]], une [[http://abs.traduc.org/abs-5.3-fr/apb.html|carte de référence]] (variables, tests...). Ce site est un site qui vaut réellement le détour pour tous ceux qui cherchent à créer des scripts complets en utilisant au mieux les performances du shell.
   * (fr) https://openclassrooms.com/courses/reprenez-le-controle-a-l-aide-de-linux : Un tutoriel très complet pour linux qui comporte quelques parties sur la réalisation de scripts bash.   * (fr) https://openclassrooms.com/courses/reprenez-le-controle-a-l-aide-de-linux : Un tutoriel très complet pour linux qui comporte quelques parties sur la réalisation de scripts bash.