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 19/09/2023, 14:21] – [L'art d'écrire un script] 146.0.160.230tutoriel:script_shell [Le 18/05/2026, 23:29] (Version actuelle) – [Méthode dans un terminal] typos krodelabestiole
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 385: Ligne 420:
     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 413: Ligne 452:
  
 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 574:
      
 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 586:
 <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 771:
 #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 784:
 <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 865:
  
 <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 916:
 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 =====