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 | ||
| console:script_shell [Le 28/11/2007, 00:53] – 152.77.24.38 | console:script_shell [Le 07/03/2008, 23:01] (Version actuelle) – Déplacé -> /tutoriel/script_shell YoBoY | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| - | {{tag> | ||
| - | ---- | ||
| - | ======Introduction aux scripts shell====== | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | ===== Présentation ===== | ||
| - | |||
| - | Un script shell est un fichier ou est écrit une ou plusieurs commandes qui sont exécuter de manier séquentielle, | ||
| - | Ces commandes ou ces codes shells appellent plusieurs fonction plus ou moin complexe et permette d' | ||
| - | |||
| - | |||
| - | === Pour faire un script intelligemment il faut respecter ces conditions: === | ||
| - | |||
| - | * Des vérifications approfondie doivent être faire sur TOUTES les commandes utilisé. | ||
| - | * Des commentaires doivent pulluler sinon le script devient bien trop transparent, | ||
| - | * Lors d'une mise a jour, un fils de discussion doit être préciser pour les bugs éventuels. | ||
| - | * Avertir les utilisateurs les dégâts que peut causer les commandes utiliser. | ||
| - | |||
| - | Evidement ces conseils sont utile au débutant... | ||
| - | <note tip> | ||
| - | Exemple: | ||
| - | Supposons que avez une base de donné, 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' | ||
| - | - calculer le nombre d' | ||
| - | ou | ||
| - | - calculer le nombre d' | ||
| - | |||
| - | Quel algorithme choisissez vous? | ||
| - | Résultat: Le premier car dans le deuxième il faut d' | ||
| - | <note help> | ||
| - | OUUUUUUIIIIIIIIIIIIIIIIIIIIIII ! | ||
| - | |||
| - | ===Ecrire un script=== | ||
| - | |||
| - | Si vous voulez écrire un programme sh, vous avez deux possibilités : | ||
| - | * soit vous tapez dans un shell toutes les commandes | ||
| - | * ou alors vous rassemblez toutes les instructions copier par ci par là dans un fichier sh. | ||
| - | |||
| - | A titre d' | ||
| - | |||
| - | #!/bin/bash | ||
| - | # indique au système que l' | ||
| - | # En cas général les "#" | ||
| - | echo Mon premier script | ||
| - | echo Liste des fichiers : | ||
| - | ls -la | ||
| - | | ||
| - | exit 0 | ||
| - | |||
| - | Le résultat de ce script est d' | ||
| - | en dessous "Liste des fichiers :", et enfin la liste des fichiers avec la | ||
| - | commande `ls -la`. | ||
| - | |||
| - | Comme vous l'avez compris, la commande `echo` sert à écrire | ||
| - | quelque chose à l' | ||
| - | |||
| - | <note warning> | ||
| - | |||
| - | |||
| - | ====Exécuter un script==== | ||
| - | D'ici, j' | ||
| - | <note help> | ||
| - | |||
| - | Et bien il suffit de se placer dans le dossier où est le script, et de lancer | ||
| - | |||
| - | bash nom_du_script | ||
| - | |||
| - | Si vous voulez l' | ||
| - | le rendre exécutable avec `chmod`. Pour ceci tapez dans le shell la commande | ||
| - | qui suit : | ||
| - | |||
| - | chmod +x nom_du_script | ||
| - | |||
| - | Puis vous pouvez exécuter le script en faisant : | ||
| - | |||
| - | ./ | ||
| - | |||
| - | ====Les différents types de shells==== | ||
| - | |||
| - | Comme vous avez sûrement du l' | ||
| - | |||
| - | * bash (//Bourne Again SHell//) : conçu par le projet GNU, shell linux ; | ||
| - | * 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,pdksh : shells korn, écrits par David Korn ; | ||
| - | * 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' | ||
| - | |||
| - | Shell (sh) est en fait un lien vers /bin/bash, tout comme rbash. | ||
| - | |||
| - | =====Les structures de contrôle===== | ||
| - | |||
| - | |||
| - | ====Les tests : `if`==== | ||
| - | Avant de commencer à faire des scripts de 1000 lignes, il serait intéressant | ||
| - | de voir comment se servir des variables, et des instructions if, then, elif, | ||
| - | else, fi. Cela permet par exemple de faire réagir le script de manière différente, | ||
| - | la réponse de l' | ||
| - | |||
| - | En bash, les variables ne se déclarent généralement pas | ||
| - | avant leurs utilisations, | ||
| - | lors de sa première mise en œuvre. | ||
| - | |||
| - | Pour pouvoir voir la valeur d'une variable il faut faire précéder son nom du caractère " | ||
| - | ==Exemple== | ||
| - | |||
| - | #!/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 `echo -n` permet de laisser le curseur sur la même ligne, ce | ||
| - | qui permet à l' | ||
| - | d' | ||
| - | |||
| - | L' | ||
| - | valeur ou un caractère à une variable quelconque, en la demandant à l' | ||
| - | (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érente des minuscules, $M != $m). | ||
| - | |||
| - | Ensuite vient l' | ||
| - | pour délimiter la condition. Attention, la variable est mise entre guillemets | ||
| - | car dans le cas où la variable est vide, le shell ne retourne pas d' | ||
| - | cas contraire, l' | ||
| - | |||
| - | [: =: unaryoperator expected | ||
| - | |||
| - | L' | ||
| - | On peut définir une table de vérité pour ces deux opérateurs, | ||
| - | |||
| - | ==Table de vérité de ||== | ||
| - | ^ Comparaison ^ Résultat ^ | ||
| - | | 0 ou 0 | 0 | | ||
| - | | 0 ou 1 | 1 | | ||
| - | | 1 ou 0 | 1 | | ||
| - | | 1 ou 1 | 1 | | ||
| - | |||
| - | Dès que l'une des deux assertions est vérifiée, la condition globale l'est aussi. | ||
| - | |||
| - | ==Table de vérité de && | ||
| - | ^ Comparaison ^ Résultat ^ | ||
| - | | 0 et 0 | 0 | | ||
| - | | 0 et 1 | 0 | | ||
| - | | 1 et 0 | 0 | | ||
| - | | 1 et 1 | 1 | | ||
| - | |||
| - | Les deux assertions doivent être vérifiées pour que la condition le soit aussi. | ||
| - | |||
| - | Enfin, on ferme le crochet, suivi d'un point virgule ou d'un saut de ligne pour exécuter la | ||
| - | commande `then` qui applique ce qui vient après, si la condition est respectée. | ||
| - | |||
| - | Les " | ||
| - | juste de facilement lire le code, de mieux se repérer. | ||
| - | |||
| - | Ensuite, `elif` sert à exécuter une autre série d' | ||
| - | |||
| - | Enfin, `else` sert à exécuter un bloc si les deux conditions précédentes ne sont pas respectées. (ah les jeunes, ils respectent plus rien de nos jours :) ). | ||
| - | |||
| - | `fi` indique la fin de notre bloc d' | ||
| - | |||
| - | J'ai quelques petites commandes pratiques à vous donner : | ||
| - | |||
| - | sh -n nom_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, | ||
| - | |||
| - | === Opérateurs de comparaison === | ||
| - | |||
| - | ^ Syntaxe ^ Fonction réalisée ^ | ||
| - | | -e fichier | ||
| - | | -d fichier | ||
| - | | -f fichier | ||
| - | | -w fichier | ||
| - | | -x fichier | ||
| - | | f1 -nt f2 | Vrai si f1 est plus récent que f2. | | ||
| - | | f1 -ot f2 | Vrai si f1 est plus vieux que f2. | | ||
| - | |||
| - | Exemple, vérifier qu'un fichier existe: | ||
| - | |||
| - | #!/bin/sh | ||
| - | | ||
| - | echo -n " | ||
| - | read file | ||
| - | if [ -e " | ||
| - | { | ||
| - | echo "Le fichier existe!" | ||
| - | } | ||
| - | else | ||
| - | { | ||
| - | echo "Le fichier n' | ||
| - | } | ||
| - | fi | ||
| - | exit 0 | ||
| - | |||
| - | La seule chose qui prête à confusion est que l'on vérifie seulement si le fichier ' | ||
| - | |||
| - | ====La commande `while`==== | ||
| - | |||
| - | La commande while exécute ce qu'il y a dans son bloc tant que la condition | ||
| - | est respectée: | ||
| - | |||
| - | #!/bin/sh | ||
| - | | ||
| - | cmpt=1 | ||
| - | cm=3 | ||
| - | echo -n "Mot de passe : " | ||
| - | read mdp | ||
| - | | ||
| - | while [ " | ||
| - | echo -n " | ||
| - | read mdp | ||
| - | cmpt=$(($cmpt+1)) | ||
| - | cm=$(($cm-1)) | ||
| - | done | ||
| - | echo "Non mais, le brute-force est interdit en France !!" | ||
| - | exit 0 | ||
| - | |||
| - | 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' | ||
| - | Je vous vois d'ici dire : | ||
| - | >mais qu' | ||
| - | 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 déterminé de fois. | ||
| - | La commande `until` fait la même chose que la commande `while` mais en inversant. | ||
| - | C'est a dire qu' | ||
| - | s' | ||
| - | |||
| - | ====La commande `case`==== | ||
| - | |||
| - | Regardons la syntaxe de cette commande, qui n'est pas une des plus simples : | ||
| - | |||
| - | 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 a 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: | ||
| - | |||
| - | #!/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 | ||
| - | exit 0 | ||
| - | |||
| - | Je crois que la seule chose qui mérite vraiment d' | ||
| - | Cela indique tout simplement l' | ||
| - | |||
| - | |||
| - | Il existe aussi plusieurs structures pour les modèles, telles que: | ||
| - | |||
| - | |||
| - | 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, | ||
| - | j'ai fait un petit script sensé refaire un prompt avec quelques commandes basiques : | ||
| - | |||
| - | #!/bin/bash | ||
| - | | ||
| - | clear | ||
| - | echo | ||
| - | echo #################### | ||
| - | echo | ||
| - | echo ############################# | ||
| - | echo -n LOGIN: | ||
| - | read login | ||
| - | echo -n Hôte: | ||
| - | 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 A 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 connect --> savoir qui est c'est dernièrement connecté;; | ||
| - | 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;; | ||
| - | | ||
| - | | ||
| - | about | --v | vers ) | ||
| - | echo Script simple pour l' | ||
| - | quit | " | ||
| - | echo Au revoir!! | ||
| - | | ||
| - | * ) | ||
| - | echo Commande inconnue;; | ||
| - | esac | ||
| - | done | ||
| - | exit 0 | ||
| - | |||
| - | ==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 je vous recommande de bien structurer le code que vous | ||
| - | écrivez. | ||
| - | |||
| - | ====La commande for==== | ||
| - | L' | ||
| - | |||
| - | for variable in valeurs; do | ||
| - | instructions | ||
| - | done | ||
| - | |||
| - | Comme vous l' | ||
| - | |||
| - | #!/bin/sh | ||
| - | for var in $(ls *.txt); do | ||
| - | echo $var | ||
| - | done | ||
| - | exit 0 | ||
| - | |||
| - | On peut voir une syntaxe un peu particulière : `$(ls *.txt)`. 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' | ||
| - | |||
| - | #!/bin/sh | ||
| - | for var in 1 2 3 4 5 6 7 8 9; do | ||
| - | echo $var | ||
| - | done | ||
| - | exit 0 | ||
| - | |||
| - | On peut très bien aussi utiliser d' | ||
| - | caractères : | ||
| - | |||
| - | #!/bin/sh | ||
| - | for var in Ubuntu Breezy 5.10; do | ||
| - | echo $var | ||
| - | done | ||
| - | exit 0 | ||
| - | |||
| - | 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 ' | ||
| - | |||
| - | nom_fonction(){ | ||
| - | instructions | ||
| - | } | ||
| - | |||
| - | Cette partie ne fait rien en elle même, elle dit juste que quand on on appellera nom_fonction, | ||
| - | |||
| - | nom_fonction | ||
| - | |||
| - | |||
| - | Rien ne vaut un petit exemple: | ||
| - | |||
| - | #!/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 | ||
| - | exit 0 | ||
| - | | ||
| - | 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' | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | ==== Lien ==== | ||
| - | |||
| - | Pour ceux qui souhaitent aller plus loin dans la conception de script shell, je vous recommande ce cours de chez developpez.com : | ||
| - | http:// | ||
| - | |||
| - | Bash parameters and parameter expansions. En anglais mais contient de nombreux exemples concernant la gestion et l' | ||
| - | http:// | ||
| - | |||
| - | ---- | ||
| - | // | ||
