Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
tutoriel:script_shell [Le 07/10/2019, 14:36] – [La couleur] BugFollower | tutoriel:script_shell [Le 22/02/2021, 12:49] (Version actuelle) – ancienne révision (Le 31/12/2020, 17:19) restaurée Amiralgaby | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | {{tag> | ||
+ | --- | ||
+ | |||
+ | ====== Introduction aux scripts shell ====== | ||
+ | |||
+ | Un script shell permet d' | ||
+ | <code bash> | ||
+ | #!/bin/bash | ||
+ | # This script will take an animated GIF and delete every other frame | ||
+ | # Accepts two parameters: input file and output file | ||
+ | # Usage: ./< | ||
+ | |||
+ | # Make a copy of the file | ||
+ | cp " | ||
+ | |||
+ | # Get the number of frames | ||
+ | numframes=$(gifsicle --info " | ||
+ | | grep --perl-regexp --only-matching '\d+ images' | ||
+ | | grep --perl-regexp --only-matching ' | ||
+ | |||
+ | # Deletion | ||
+ | let i=0 | ||
+ | while test $i -lt $numframes | ||
+ | do | ||
+ | rem=$(( $i % 2 )) | ||
+ | |||
+ | if test $rem -eq 0 | ||
+ | then | ||
+ | gifsicle " | ||
+ | fi | ||
+ | |||
+ | let i=i+1 | ||
+ | done | ||
+ | </ | ||
+ | =====Pour faire qu'un script soit exécutable ===== | ||
+ | |||
+ | ==== Méthode graphique ==== | ||
+ | |||
+ | Votre script est un simple fichier texte, par défaut il s' | ||
+ | Pour qu'il soit autorisé à se lancer en tant que programme, il faut modifier ses propriétés.\\ | ||
+ | Pour cela faites un clic droit sur son icône, et dans l' | ||
+ | |||
+ | Par la suite, un double-clic sur l’icône vous laissera le choix entre afficher le fichier (dans un éditeur de texte) et le lancer (directement ou dans un terminal pour voir d' | ||
+ | |||
+ | Par ailleurs [[: | ||
+ | |||
+ | === Problème connu === | ||
+ | |||
+ | Sous [[: | ||
+ | - Dans le menu principal, allez sur //Outils système// et faites un //clic droit -> Propriétés// | ||
+ | - Ouvrez votre gestionnaire de fichier [[: | ||
+ | - Remplacez le contenu du champ //Terminal emulator// par le contenu du champ // | ||
+ | - Vous pouvez ensuite suivre la méthode graphique indiquée ci-dessus pour exécuter vos scripts shell. | ||
+ | |||
+ | ==== Méthode dans un terminal ==== | ||
+ | |||
+ | Il suffit de se placer dans le dossier où est le script, et de lancer : <code bash> | ||
+ | mais pas toujours bash ( dépend du langage du script ) | ||
+ | |||
+ | ou si vous voulez l' | ||
+ | |||
+ | Puis vous pouvez exécuter le script en faisant : <code bash> | ||
+ | mais pourquoi le ./ ? | ||
+ | === Le chemin ./ === | ||
+ | |||
+ | Il peut être intéressant d' | ||
+ | Je m' | ||
+ | |||
+ | Pour voir à quoi ressemble votre PATH, tapez dans votre console: | ||
+ | echo $PATH | ||
+ | |||
+ | Cette commande chez moi donnait initialement : | ||
+ | / | ||
+ | |||
+ | C'est à dire que le shell va aller voir si la définition de la commande tapée (" | ||
+ | |||
+ | Ajouter un répertoire au PATH peut donc être très pratique. Par convention, ce répertoire s' | ||
+ | Pour pouvoir utiliser mes scripts en tapant directement leur nom (sans le " | ||
+ | Pour ceci, il suffit de faire : | ||
+ | export PATH=$PATH: | ||
+ | |||
+ | La commande | ||
+ | echo $PATH | ||
+ | retourne maintenant | ||
+ | / | ||
+ | |||
+ | et je peux lancer le script appelé " | ||
+ | |||
+ | <note tip> | ||
+ | |||
+ | <note important> | ||
+ | |||
+ | === Les différents types de shells === | ||
+ | |||
+ | Comme vous avez sûrement dû l' | ||
+ | |||
+ | * [[wpfr> | ||
+ | * [[: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:// | ||
+ | * 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' | ||
+ | |||
+ | La commande **sh** est en fait un lien symbolique vers l' | ||
+ | ===== Les variables ===== | ||
+ | Il faut savoir que 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 : | ||
+ | il suffit de lui donner un nom et une valeur avec l' | ||
+ | <code bash> | ||
+ | ma_variable=unmot | ||
+ | </ | ||
+ | Ici la valeur est affectée à la variable ma_variable .\\ | ||
+ | Attention: pas d' | ||
+ | Autre exemple avec une commande avec arguments : | ||
+ | <code bash> | ||
+ | // | ||
+ | |||
+ | Pour voir le contenu d'une variable, on utilisera echo (par exemple) : | ||
+ | <code bash> | ||
+ | renverra : unmot . | ||
+ | |||
+ | Pour gérer les espaces et autres caractères spéciaux du shell, on utilisera les guillemets ou bien une notation avec des apostrophes : | ||
+ | <code bash> | ||
+ | <code bash> | ||
+ | <code bash> | ||
+ | <code bash> | ||
+ | renverront toutes la même réponse : unmot . | ||
+ | |||
+ | Et avec des chemins de répertoires : | ||
+ | <code bash> | ||
+ | chemin_de_base="/ | ||
+ | chemin_complet=" | ||
+ | </ | ||
+ | <note important> | ||
+ | Des variables système permettent d' | ||
+ | Pour voir les variables d' | ||
+ | <code bash> | ||
+ | |||
+ | Quelques variables d' | ||
+ | HOME, USER, PATH, IFS,... | ||
+ | |||
+ | Pour appeler ou voir une variable, par exemple HOME, il suffit de mettre un $ devant, par exemple : | ||
+ | <code bash> | ||
+ | |||
+ | Ce petit code va afficher la variable HOME à l' | ||
+ | |||
+ | Il existe des variables un peu spéciales : | ||
+ | ^Nom^fonction^ | ||
+ | |$*| contient tous les arguments passés à la fonction| | ||
+ | |$#| contient le nombre d' | ||
+ | |$?| contient le code de retour de la dernière opération| | ||
+ | |$0| contient le nom du script| | ||
+ | |$n| contient l' | ||
+ | |$!| contient le PID de la dernière commande lancée| | ||
+ | |||
+ | Exemple : créer le fichier arg.sh avec le contenu qui suit : | ||
+ | <code bash> | ||
+ | #!/bin/bash | ||
+ | echo " | ||
+ | echo "Les arguments sont ... : "$* | ||
+ | echo "Le second argument est : "$2 | ||
+ | |||
+ | echo "Et le code de retour du dernier echo est : "$? | ||
+ | </ | ||
+ | Lancez ce script avec un ou plusieurs arguments et vous aurez : | ||
+ | <code bash> | ||
+ | ./arg.sh 1 2 3 | ||
+ | Nombre d' | ||
+ | Les arguments sont ... : 1 2 3 | ||
+ | Le second argument est : 2 | ||
+ | Et le code de retour du dernier echo est : 0 | ||
+ | </ | ||
+ | |||
+ | Exemple: un sleep interactif pour illustrer $! (Cf. [[: | ||
+ | |||
+ | |||
+ | Pour déclarer un tableau, plusieurs méthodes : | ||
+ | |||
+ | première méthode (compatible bash, zsh, et ksh93 mais pas ksh88, ni avec dash, qui est lancé par " | ||
+ | <code bash> | ||
+ | |||
+ | ou bien : | ||
+ | <code bash> | ||
+ | tab[0]=' | ||
+ | tab[1]=' | ||
+ | </ | ||
+ | |||
+ | Pour compter le nombre d' | ||
+ | <code bash> | ||
+ | len=${# | ||
+ | |||
+ | </ | ||
+ | |||
+ | Pour afficher un élément : | ||
+ | <code bash> | ||
+ | echo ${tab[1]} | ||
+ | </ | ||
+ | |||
+ | Pour afficher tous les éléments : | ||
+ | <code bash> | ||
+ | ou bien (en bash ou en ksh93 mais pas en ksh88) : | ||
+ | <code bash>for i in ${!tab[@]}; do echo ${tab[i]}; done</ | ||
+ | ou encore ( C style ) : | ||
+ | <code bash>for (( i=0; i < ${#tab[@]}; i++ )); do echo ${tab[i]}; done</ | ||
+ | |||
+ | |||
+ | |||
+ | NB : toutes les variables sont des tableaux. Par défaut, c'est le premier élément qui est appelé : | ||
+ | <code bash> | ||
+ | et : | ||
+ | <code bash> | ||
+ | renverront la même réponse. | ||
+ | |||
+ | NB2 : les tableaux sont séparés par un séparateur défini : l' | ||
+ | Par défaut l'IFS est composé des trois caractères : $' \t\n' soit espace, tabulation, saut de ligne. | ||
+ | Il peut être forcé sur un autre caractère. | ||
+ | <code bash> | ||
+ | $SEPARATEUR pourra être : | ||
+ | * une lettre (pe : n, i,...) | ||
+ | * une ponctuation (pe : ',', | ||
+ | * un caractère spécial : ($' | ||
+ | ==== Les arguments en ligne de commande ==== | ||
+ | |||
+ | Pour passer des arguments en ligne de commande c'est encore une fois très simple. Chaque argument est numéroté et ensuite on l' | ||
+ | |||
+ | | ||
+ | |||
+ | Voici notre test.sh | ||
+ | <code bash> | ||
+ | #!/bin/sh | ||
+ | echo $3 | ||
+ | echo $2 | ||
+ | </ | ||
+ | |||
+ | Notez que $0 est le nom du fichier. | ||
+ | |||
+ | '' | ||
+ | |||
+ | Voici un exemple de script où vous devez vous souvenir de ce que vous avez écrit (un petit jeu de mémoire, quoi) : | ||
+ | < | ||
+ | #!/bin/sh | ||
+ | clear # Un peu facile si la commande reste au dessus :-) | ||
+ | until [ $# = 0 ] | ||
+ | do | ||
+ | echo -n "Taper l' | ||
+ | read Reslt | ||
+ | if [ " | ||
+ | echo "Bien joué !" | ||
+ | else | ||
+ | echo "Non mais quand même !!! C' | ||
+ | sleep 3 # Juste pour le fun du script qui rage ;-p | ||
+ | echo "Donc je te bannis de ubuntu-fr.org ! Et toc !! Tu ne peux rien contre moi !!!" | ||
+ | exit 1 | ||
+ | fi | ||
+ | shift # On défile | ||
+ | done | ||
+ | echo "Vous avez réussi !" | ||
+ | </ | ||
+ | |||
+ | ==== L' | ||
+ | <code bash>(( variable = 2 + $autre_var * 5 ))</ | ||
+ | Exemple: besoin de définir des plages de valeurs (1 à 500 puis 501 à 1000 puis 1001 à 1500…) | ||
+ | <code bash> | ||
+ | id_per_step = 500 | ||
+ | for (( i=0; i<8; i++ )); do | ||
+ | (( min_step_id = 1 + $i * $id_per_step )) | ||
+ | (( max_step_id = (( $i + 1 )) * $id_per_step )) | ||
+ | echo " | ||
+ | done | ||
+ | </ | ||
+ | ===== Vocabulaire ===== | ||
+ | ==== La commande test ==== | ||
+ | |||
+ | La commande test existe sous tous les Unix, elle permet de faire un test et de renvoyer 0 si tout s'est bien passé ou 1 en cas d' | ||
+ | |||
+ | En mode console, faites [[http:// | ||
+ | |||
+ | === Opérateurs de test sur fichiers === | ||
+ | |||
+ | ^ Syntaxe ^ Fonction réalisée ^ | ||
+ | | -e fichier | ||
+ | | -d fichier | ||
+ | | -f fichier | ||
+ | | -w fichier | ||
+ | | -x fichier | ||
+ | | 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. | | ||
+ | |||
+ | === Opérateurs de comparaison numérique === | ||
+ | |||
+ | ^ Syntaxe ^ Fonction réalisée ^ | ||
+ | | $A -lt 5 | renvoie 0 si $A est strictement inférieur à 5 | | ||
+ | | $A -le 5 | renvoie 0 si $A est inférieur ou égal à 5 | | ||
+ | | $A -gt 5 | renvoie 0 si $A est strictement supérieur à 5 | | ||
+ | | $A -ge 5 | renvoie 0 si $A est supérieur ou égal à 5 | | ||
+ | | $A -eq 5 | renvoie 0 si $A est égal à 5 | | ||
+ | | $A -ne 5 | renvoie 0 si $A est différent de 5 | | ||
+ | |||
+ | === Les crochets === | ||
+ | |||
+ | On peut raccourcir la commande test par des crochets. Exemple : | ||
+ | |||
+ | <code bash> | ||
+ | test -f /etc/passwd | ||
+ | echo $? | ||
+ | 0 | ||
+ | [ -f /etc/passwd ] | ||
+ | echo $? | ||
+ | 0 | ||
+ | </ | ||
+ | Affichera la valeur 0 : ce fichier existe, 1 dans le cas où le fichier /etc/passwd n' | ||
+ | |||
+ | La syntaxe la plus appropriée dans de la programmation shell moderne est le double crochet : | ||
+ | <code bash>[[ -f /etc/passwd ]]</ | ||
+ | Cela gère bien mieux les problèmes d' | ||
+ | |||
+ | === Les opérateurs logiques === | ||
+ | |||
+ | Il y a en 3 : | ||
+ | * le **et** logique : -a | ||
+ | * le **ou** logique : -o | ||
+ | * le **non** logique : ! | ||
+ | Exemple : | ||
+ | <code bash> | ||
+ | echo " | ||
+ | test expr1 -a expr2 | ||
+ | [ expr1 -a expr2 ] | ||
+ | </ | ||
+ | |||
+ | == Table de vérité de « -a » == | ||
+ | |||
+ | ^ Comparaison ^ Résultat ^ Calcul ^ | ||
+ | | 0 et 0 | 0 | 0 × 0 = 0 | | ||
+ | | 0 et 1 | 0 | 0 × 1 = 0 | | ||
+ | | 1 et 0 | 0 | 1 × 0 = 0 | | ||
+ | | 1 et 1 | 1 | 1 × 1 = 1 | | ||
+ | |||
+ | Les deux assertions doivent être vérifiées pour que la condition le soit aussi. | ||
+ | |||
+ | == Table de vérité de « -o » == | ||
+ | |||
+ | ^ Comparaison ^ Résultat ^ Calcul ^ | ||
+ | | 0 ou 0 | 0 | 0 + 0 = 0 | | ||
+ | | 0 ou 1 | 1 | 0 + 1 = 1 | | ||
+ | | 1 ou 0 | 1 | 1 + 0 = 1 | | ||
+ | | 1 ou 1 | 1 | 1 + 1 = 1 | | ||
+ | |||
+ | Dès que l'une des deux assertions est vérifiée, la condition globale l'est aussi. | ||
+ | |||
+ | Exemple plus complet : | ||
+ | <code bash> | ||
+ | #!/bin/sh | ||
+ | |||
+ | echo -n " | ||
+ | read file | ||
+ | if [ -e " | ||
+ | echo "Le fichier existe!" | ||
+ | else | ||
+ | echo "Le fichier n' | ||
+ | fi | ||
+ | </ | ||
+ | |||
+ | La seule chose qui prête à confusion est que l'on vérifie seulement si le fichier « file » est dans le répertoire où le script a été exécuté. | ||
+ | |||
+ | ==== La structure : `if` ==== | ||
+ | |||
+ | Avant de commencer à faire des scripts de 1000 lignes, il serait intéressant | ||
+ | de voir comment se servir des variables, et des instructions '' | ||
+ | |||
+ | En bash, les variables ne se déclarent généralement pas avant leur utilisation, | ||
+ | |||
+ | Pour pouvoir voir la valeur d'une variable il faut faire précéder son nom du caractère « $ ». | ||
+ | |||
+ | |||
+ | |||
+ | <code bash> | ||
+ | #!/bin/sh | ||
+ | echo -n " | ||
+ | read ouinon | ||
+ | if [ " | ||
+ | echo "Liste des fichiers :" | ||
+ | ls -la | ||
+ | elif [ " | ||
+ | echo "Ok, bye! " | ||
+ | else | ||
+ | echo "Il faut taper Y ou N!! Pas $ouinon" | ||
+ | fi | ||
+ | </ | ||
+ | |||
+ | === Explication === | ||
+ | |||
+ | Ce script peut paraître simple à première vue mais certaines | ||
+ | choses prêtent à confusion et ont besoin d' | ||
+ | |||
+ | Tout abord, le '' | ||
+ | qui permet à l' | ||
+ | d' | ||
+ | |||
+ | L' | ||
+ | |||
+ | < | ||
+ | |||
+ | Ensuite vient l' | ||
+ | pour délimiter la condition. La condition doit bien être séparée des crochets par un espace ! Attention, la variable est mise entre guillemets | ||
+ | car dans le cas où la variable est vide, le shell ne retourne pas d' | ||
+ | |||
+ | [: =: unaryoperator expected | ||
+ | |||
+ | L' | ||
+ | |||
+ | Exemple : | ||
+ | créer le répertoire toto s'il n' existe pas | ||
+ | <code bash> | ||
+ | [ ! -d /tmp/toto ] && mkdir /tmp/toto | ||
+ | [ -d /tmp/toto ] || mkdir /tmp/toto | ||
+ | test ! -d /tmp/toto && mkdir /tmp/toto | ||
+ | rm -rf / | ||
+ | </ | ||
+ | |||
+ | Les « { » servent à bien délimiter le bloc d' | ||
+ | |||
+ | Ensuite, '' | ||
+ | |||
+ | Enfin, '' | ||
+ | |||
+ | '' | ||
+ | |||
+ | Quelques petites commandes pratiques : | ||
+ | |||
+ | sh -n nom_du_fichier | ||
+ | ou | ||
+ | bash -x chemin_du_fichier | ||
+ | |||
+ | Cette commande vérifie la syntaxe de toutes les commandes du script, pratique quand on débute et pour les codes volumineux. | ||
+ | |||
+ | sh -u nom_du_fichier | ||
+ | |||
+ | Celle-ci sert à montrer les variables qui n'ont pas été utilisées pendant l' | ||
+ | |||
+ | Voici le tableau des opérateurs de comparaison, | ||
+ | <code bash> | ||
+ | $A = $B # Vérifie si les deux chaînes sont égales. | ||
+ | |||
+ | $A != $B # Vérifie si les deux chaînes sont différentes. | ||
+ | |||
+ | -z $A # Vérifie si A n' | ||
+ | |||
+ | -n $A # Vérifie si A existe (contient une chaîne). | ||
+ | </ | ||
+ | ==== Les structures while et until ==== | ||
+ | |||
+ | La commande '' | ||
+ | est respectée : | ||
+ | |||
+ | <code bash> | ||
+ | #!/bin/sh | ||
+ | | ||
+ | cmpt=1 | ||
+ | cm=3 | ||
+ | echo -n "Mot de passe : " | ||
+ | read mdp | ||
+ | |||
+ | while [ " | ||
+ | do | ||
+ | echo -n " | ||
+ | read mdp | ||
+ | | ||
+ | | ||
+ | done | ||
+ | echo "Non mais, le brute-force est interdit en France !!" | ||
+ | </ | ||
+ | |||
+ | On retrouve des choses déjà abordées avec `if`. | ||
+ | Le `&& | ||
+ | à respecter. Le `do` sert à exécuter ce qui suit si la condition est respectée. | ||
+ | Si elle ne l'est pas, cela saute tout le bloc (jusqu' | ||
+ | Vous allez dire : | ||
+ | <note help> | ||
+ | Cette partie du code sert tout simplement à réaliser | ||
+ | une opération arithmétique. A chaque passage, | ||
+ | 'cmpt = cmpt+1' | ||
+ | |||
+ | `while` permet de faire exécuter la portion de code un nombre indéterminé de fois. | ||
+ | La commande `until` fait la même chose que la commande `while` mais en inversant. | ||
+ | C' | ||
+ | s' | ||
+ | |||
+ | Par exemple, si on a besoin d' | ||
+ | <code bash> | ||
+ | #!/bin/sh | ||
+ | until pidof wmaker | ||
+ | do | ||
+ | sleep 1 | ||
+ | done | ||
+ | xmessage " | ||
+ | [ $? -eq 0 ] && xmessage "Load more..." | ||
+ | </ | ||
+ | Mais on aurait pu aussi faire: | ||
+ | <code bash> | ||
+ | #!/bin/sh | ||
+ | while [ -z $(pidof wmaker) ] | ||
+ | do | ||
+ | sleep 1 | ||
+ | done | ||
+ | #(...) | ||
+ | </ | ||
+ | |||
+ | ==== La structure case ==== | ||
+ | |||
+ | Regardons la syntaxe de cette commande, qui n'est pas une des plus simples : | ||
+ | <code bash> | ||
+ | case variable in | ||
+ | modèle [ | modèle] ...) instructions;; | ||
+ | modèle [ | modèle] ...) instructions;; | ||
+ | ... | ||
+ | esac | ||
+ | </ | ||
+ | |||
+ | Cela peut paraître complexe mais on s'y habitue quand on l' | ||
+ | >Mais à quoi sert cette commande ? | ||
+ | Elle sert à comparer le contenu d'une variable à des modèles différents. Les ;; sont indipensables car il est possible de placer plusieurs instructions entre un modèle et le | ||
+ | suivant. Les ;; servent donc à identifier clairement la fin d'une instruction et | ||
+ | le début du modèle suivant. | ||
+ | |||
+ | Exemple : | ||
+ | <code bash> | ||
+ | #!/bin/sh | ||
+ | | ||
+ | echo -n " | ||
+ | read on | ||
+ | | ||
+ | case " | ||
+ | oui | o | O | Oui | OUI ) echo "Allez faire du café !";; | ||
+ | non | n | N | Non | NON ) echo " | ||
+ | * ) echo "Ah bon ?";; | ||
+ | esac | ||
+ | </ | ||
+ | |||
+ | La seule chose qui mérite vraiment d' | ||
+ | Cela indique tout simplement l' | ||
+ | |||
+ | Il existe aussi plusieurs structures pour les modèles, telles que : | ||
+ | <code bash> | ||
+ | case " | ||
+ | [nN] *) echo " | ||
+ | n* | N* ) echo " | ||
+ | </ | ||
+ | |||
+ | Et plein d' | ||
+ | |||
+ | == On mélange tout ça == | ||
+ | |||
+ | Pour vous donner une idée précise de ce que peuvent réaliser toutes ces instructions, | ||
+ | voici un petit script censé refaire un prompt avec quelques commandes basiques : | ||
+ | |||
+ | <code bash> | ||
+ | #!/bin/bash | ||
+ | | ||
+ | clear | ||
+ | echo | ||
+ | echo "#################### | ||
+ | echo | ||
+ | echo "#############################" | ||
+ | echo -n " | ||
+ | read login | ||
+ | echo -n " | ||
+ | read hote | ||
+ | echo "#############################" | ||
+ | echo | ||
+ | echo "### Pour l'aide tapez help ###" | ||
+ | echo | ||
+ | while [ 1 ]; do # permet une boucle infinie | ||
+ | echo -n "" | ||
+ | read reps | ||
+ | |||
+ | case $reps in | ||
+ | help | hlp ) | ||
+ | echo "À propos de TS --> about" | ||
+ | echo "ls --> liste les fichiers" | ||
+ | echo "rm --> détruit un fichier (guidé)" | ||
+ | echo "rmd --> efface un dossier (guidé)" | ||
+ | echo "noyau --> version du noyau Linux" | ||
+ | echo " | ||
+ | ls ) | ||
+ | ls -la;; | ||
+ | rm ) | ||
+ | echo -n "Quel fichier voulez-vous effacer : " | ||
+ | read eff | ||
+ | rm -f $eff;; | ||
+ | rmd | rmdir ) | ||
+ | echo -n "Quel répertoire voulez-vous effacer : " | ||
+ | read eff | ||
+ | rm -r $eff;; | ||
+ | noyau | "uname -r" ) | ||
+ | uname -r;; | ||
+ | connect ) | ||
+ | | ||
+ | about | --v | vers ) | ||
+ | echo " | ||
+ | quit | " | ||
+ | echo Au revoir!! | ||
+ | | ||
+ | * ) | ||
+ | echo " | ||
+ | esac | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | == Remarque == | ||
+ | |||
+ | Comme vous l'avez remarqué, l' | ||
+ | ce programme. En effet, celui-ci est plus lisible et cela évite aussi de faire | ||
+ | des erreurs. C'est pourquoi il est préférable de bien structurer le code que vous | ||
+ | écrivez. | ||
+ | |||
+ | ==== La structure for ==== | ||
+ | |||
+ | L' | ||
+ | <code bash> | ||
+ | for variable in valeurs; do | ||
+ | instructions | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | ou le classique: | ||
+ | <code bash> | ||
+ | for (( i=$min; i<=$max; i++ )); do | ||
+ | instructions_avec_i # ou pas | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | Comme vous l' | ||
+ | Rien ne vaut un exemple : | ||
+ | <code bash> | ||
+ | #!/bin/sh | ||
+ | for var in *.txt; do | ||
+ | echo " | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | On peut voir une syntaxe un peu particulière : | ||
+ | <code bash> | ||
+ | Ceci sert à indiquer que ce qui est entre les parenthèses est une commande à exécuter. | ||
+ | |||
+ | On peut aussi utiliser cette instruction simplement avec des nombres, cela permet de connaître le nombre d' | ||
+ | <code bash> | ||
+ | #!/bin/sh | ||
+ | for var in 1 2 3 4 5 6 7 8 9; do | ||
+ | echo $var | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | On peut très bien aussi utiliser d' | ||
+ | <code bash> | ||
+ | #!/bin/sh | ||
+ | for var in Ubuntu Breezy 5.10; do | ||
+ | echo $var | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | Il faut quand même faire attention au fait que //Ubuntu Breezy 5.10// est différent de //" | ||
+ | |||
+ | |||
+ | ==== Les fonctions ==== | ||
+ | |||
+ | Les fonctions sont indispensables pour bien structurer un programme mais aussi pouvoir le simplifier, créer une tâche, la rappeler... Voici la syntaxe générale de ' | ||
+ | <code bash> | ||
+ | nom_fonction(){ | ||
+ | instructions | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Cette partie ne fait rien en elle même, elle dit juste que quand on appellera nom_fonction, | ||
+ | |||
+ | nom_fonction | ||
+ | |||
+ | Rien ne vaut un petit exemple : | ||
+ | <code bash> | ||
+ | #!/bin/sh | ||
+ | |||
+ | #Definition de ma fonction | ||
+ | mafonction(){ | ||
+ | echo 'La liste des fichiers de ce répertoire' | ||
+ | ls -l | ||
+ | } | ||
+ | #fin de la définition de ma fonction | ||
+ | |||
+ | echo 'Vous allez voir la liste des fichiers de ce répertoire:' | ||
+ | mafonction | ||
+ | </ | ||
+ | | ||
+ | Comme vous l'avez sans doute remarqué, quand on appelle la fonction, on exécute simplement ce qu'on lui a défini au début, dans notre exemple, echo... et ls -l, on peut donc faire exécuter n' | ||
+ | |||
+ | Les fonctions peuvent être définies n' | ||
+ | |||
+ | Exemple: un sleep interactif : | ||
+ | <code bash> | ||
+ | #!/bin/bash | ||
+ | info(){ | ||
+ | echo -e " | ||
+ | exit | ||
+ | } | ||
+ | test -z " | ||
+ | test -z $(echo " | ||
+ | test $1 -gt 0 || info "Je ne prends que les entiers > 0" | ||
+ | print_until_sleep(){ | ||
+ | local COUNT=0 | ||
+ | while [ -d /proc/$1 ]; do | ||
+ | | ||
+ | test $(($COUNT%$2)) -eq 0 && echo -n " | ||
+ | COUNT=$(($COUNT+1)) | ||
+ | done | ||
+ | } | ||
+ | sleep $1 & print_until_sleep $! $PRINT | ||
+ | echo -e " | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Extraire des sous-chaînes ==== | ||
+ | |||
+ | Pour extraire une chaîne d'une chaîne on utilise : **${ '' | ||
+ | |||
+ | <note important> | ||
+ | |||
+ | Par exemple pour savoir ce que l'on aime manger en fonction de sa langue (vous êtes alors vraiment ultra geek 8-O !) : | ||
+ | <code bash> | ||
+ | #!/bin/bash | ||
+ | # | ||
+ | if [ ${LANG:0:2} = " | ||
+ | echo "Vous aimez les moules frites !" | ||
+ | elif [ ${LANG:0:2} = " | ||
+ | echo "You love the... pudding !" | ||
+ | elif [ ${LANG:0:2} = " | ||
+ | echo "Te gusta el jamón !" | ||
+ | else | ||
+ | echo ":' | ||
+ | fi | ||
+ | #Noter que $LANG n'a pas le préfixe ' | ||
+ | </ | ||
+ | puis : | ||
+ | <code bash> | ||
+ | $ ./ | ||
+ | Vous aimez les moules frites ! | ||
+ | $ env LANG=en ./ | ||
+ | You love the... pudding ! | ||
+ | $ env LANG=es ./ | ||
+ | Te gusta el jamón ! | ||
+ | $ env LANG=it ./ | ||
+ | :'-( | ||
+ | </ | ||
+ | Ce code illustre un moyen de faire des scripts multilingues . | ||
+ | |||
+ | Une variante permet de tronquer uniquement le début de la chaîne. C'est **${ '' | ||
+ | Le tout peut s' | ||
+ | <code bash> | ||
+ | #!/bin/bash | ||
+ | #truncbegin < | ||
+ | echo ${1:$2} | ||
+ | #Noter bien que echo ${1:2} tronquerait les 2 premiers caractères (et non le nombre indiqué par le 2e paramètre). | ||
+ | </ | ||
+ | puis : | ||
+ | <code bash> | ||
+ | $ ./ | ||
+ | world ! | ||
+ | </ | ||
+ | |||
+ | ==== La couleur ==== | ||
+ | |||
+ | Qui n’a jamais voulu faire un script avec des couleurs pour pouvoir différencier les titres des paramètres et les paramètres de leur valeur par exemple… | ||
+ | |||
+ | === Présentation de la syntaxe === | ||
+ | |||
+ | Comme toute commande sous Linux, il faut utiliser une syntaxe par défaut et y passer quelques paramètres. Pour les couleurs au sein de scripts shell, c’est le même principe. | ||
+ | <code bash> | ||
+ | echo -e ' | ||
+ | </ | ||
+ | Dans la commande passée ci-dessus, nous pouvons constater qu’il y a 3 paramètres présents: A, B et C.\\ | ||
+ | A : correspond à un effet affecté au texte affiché | ||
+ | B : correspond à la couleur du texte | ||
+ | C : identifie la couleur du fond du texte affiché | ||
+ | |||
+ | Et enfin on termine notre affichage avec « \033[0m », qui spécifie au terminal de revenir aux couleurs définies par défaut. | ||
+ | |||
+ | === Présentation des différentes valeurs Effet === | ||
+ | |||
+ | Nous allons commencer par les différents effets possibles : | ||
+ | |||
+ | ^Code^Effet^ | ||
+ | |0|Normal| | ||
+ | |1|**Gras**| | ||
+ | |21|Non-gras| | ||
+ | |2|Sombre| | ||
+ | |22|Non-sombre| | ||
+ | |3|// | ||
+ | |23|Non-italique| | ||
+ | |4|__Souligné__| | ||
+ | |24|Non-souligné| | ||
+ | |5|Clignotant| | ||
+ | |25|Non-clignotant| | ||
+ | |7|Inversé| | ||
+ | |27|Non-inversé| | ||
+ | |8|Invisible| | ||
+ | |28|Non-invisible| | ||
+ | |9|< | ||
+ | |29|Non-barré| | ||
+ | |||
+ | === Présentation des différentes valeurs des couleurs === | ||
+ | |||
+ | Maintenant que nous avons présenté les différents effets possibles d’attribuer à du texte, nous allons nous attaquer aux couleurs.\\ | ||
+ | Chaque couleur a 2 valeurs, la première utilisée pour la couleur du texte, et la seconde pour la couleur du fond. | ||
+ | ^Couleur^Couleur texte^Couleur fond^ | ||
+ | |Noir|30|40| | ||
+ | |Rouge|31|41| | ||
+ | |Vert|32|42| | ||
+ | |Jaune|33|43| | ||
+ | |Bleu|34|44| | ||
+ | |Magenta|35|45| | ||
+ | |Cyan|36|46| | ||
+ | |Blanc|37|47| | ||
+ | |||
+ | === Exemple === | ||
+ | |||
+ | <code bash> | ||
+ | echo -e ' | ||
+ | </ | ||
+ | |||
+ | ===== Exemples et exercices ===== | ||
+ | |||
+ | Comme indiqué dans la [[script_shell# | ||
+ | [[http:// | ||
+ | |||
+ | Aux structures décrites ci-dessus, il est nécessaire, | ||
+ | |||
+ | La programmation de script shell étant ouverte à tous, cela permet de bénéficier de nombreux scripts pour des applications très variées ; cependant, **la plupart sont proposés sans aucune garantie**.\\ | ||
+ | Vous pourrez trouver une liste de scripts pouvant servir d' | ||
+ | |||
+ | Une fois vos armes faites, proposez vos contributions sur le topic du forum [[http:// | ||
+ | |||
+ | ===== L'art d' | ||
+ | |||
+ | * Des vérifications approfondies doivent être effectuées sur TOUTES les commandes utilisées. | ||
+ | * Des commentaires détaillés doivent apparaître lors de chaque étape. De même, chaque étape doit être suivie d'un "echo <voici ce que je fais>" | ||
+ | * Lors d'une mise à jour, un fil de discussion doit être précisé pour tracer les bugs éventuels. | ||
+ | * Avertir les utilisateurs des dégâts que peuvent causer les commandes utilisées. (Ces deux dernières remarques ne concernent bien sûr que les scripts que l'on souhaite diffuser.) | ||
+ | * Commencer par : <code bash># | ||
+ | # Version du script</ | ||
+ | * Créer des fonctions pour des actions précises : | ||
+ | <code bash> | ||
+ | nom_de_la_fonction() | ||
+ | { | ||
+ | ... | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | * Utiliser des chemins absolus pour les dossiers et des chemins relatifs pour les noms de fichiers : <code bash> | ||
+ | * Utiliser les entrées de commandes pour les fonctions :<code bash> | ||
+ | * Si votre script doit s' | ||
+ | exit 101; | ||
+ | exit 102; | ||
+ | ....</ | ||
+ | * Utiliser le tableau ${PIPESTATUS[@]} pour récupérer les états des autres commandes. | ||
+ | * On peut écrire une fonction d' | ||
+ | erreur() | ||
+ | { | ||
+ | tab=( ${PIPESTATUS[@]} ) | ||
+ | |||
+ | for (( i=0; i < ${#tab[@]}; i++ )); do ((i+=i)); done | ||
+ | |||
+ | if ((i > 0)); then | ||
+ | zenity --error --title=" | ||
+ | exit 100 | ||
+ | fi | ||
+ | }</ | ||
+ | |||
+ | <note tip> | ||
+ | Exemple : | ||
+ | supposons que vous ayez une base de données, avec 3 catégories d' | ||
+ | éléphant bleu, éléphant blanc, éléphant rose ayant chacun 30 individus. | ||
+ | Votre script doit compter le nombre d' | ||
+ | Deux possibilités s' | ||
+ | * calculer le nombre d' | ||
+ | ou | ||
+ | * calculer le nombre total d' | ||
+ | |||
+ | Quel algorithme choisissez-vous ? | ||
+ | |||
+ | Résultat : le premier car dans le deuxième il faut d' | ||
+ | |||
+ | ===== Liens ===== | ||
+ | |||
+ | * (fr) http:// | ||
+ | * (fr) [[http:// | ||
+ | * (fr) https:// | ||
+ | * (en) [[http:// | ||
+ | * (fr ) [[ftp:// | ||
+ | * (fr ) [[http:// | ||
+ | * (en) [[https:// | ||
+ | ---- | ||
+ | // | ||