Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédente | |||
| tutoriel:script_shell [Le 21/02/2021, 18:23] – 196.65.93.130 | 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:// | ||
| + | ---- | ||
| + | // | ||
