informatique:linux:programmation_shell
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
informatique:linux:programmation_shell [2009/12/22 16:30] – pteu | informatique:linux:programmation_shell [2021/01/24 11:41] – [Ressources] pteu | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | {{tag> | ||
- | ====== Programmation Shell ======= | + | ======Programmation Shell======= |
+ | {{ : | ||
- | * '' | + | Les différents shells peuvent avoir des fonctions sensiblement différentes voir incompatibles. Ce n'est pas le cas pour la majorité d'entre elles. Ici nous parlerons |
- | ===== Les " | + | Pour afficher la liste des options de bash il faut saisir '' |
+ | |||
+ | Les mots d'une ligne suivants un ''#'' | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | <code bash> | ||
+ | $ touch toto | ||
+ | $ echo !! | ||
+ | echo touch toto | ||
+ | touch toto | ||
+ | </ | ||
+ | |||
+ | |||
+ | ======Les | ||
+ | |||
+ | En bash, chaque variable est précédée de '' | ||
+ | <code bash> | ||
+ | NOM="robert" | ||
+ | echo " | ||
+ | </ | ||
+ | On peut les manipuler sans les déclarer proprement au préalable ; mais on peut être clean et les définir ('' | ||
+ | |||
+ | Pour déclarer une variable non modifiable = en readonly (une constante) : | ||
+ | <code bash> | ||
+ | readonly CONST=" | ||
+ | # ou | ||
+ | declare -r CONST=" | ||
+ | </ | ||
+ | |||
+ | Par défaut une variable est globale et est vue dans le script (y compris ses fonctions) ; dans une fonction on peut déclarer des variables locales afin d' | ||
+ | <code bash> | ||
+ | local VAR=" | ||
+ | </ | ||
+ | <WRAP center round important 60%> | ||
+ | Les variables déclarées dans une fonction ont toujours une portée locale (elles sont détruites à la fin de la fonction), à moins qu' | ||
+ | </ | ||
+ | |||
+ | |||
+ | Pour déclarer une constante locale à une fonction : | ||
+ | <code bash> | ||
+ | local -r CONST=" | ||
+ | |||
+ | # ou en 2 lignes | ||
+ | local CONST=" | ||
+ | readonly CONST | ||
+ | |||
+ | # marche aussi, puisque lorsque declare est invoqué dans une fonction, | ||
+ | # la variable qui suit est déclarée localement | ||
+ | function test() { | ||
+ | declare -r CONST=" | ||
+ | } | ||
+ | </ | ||
+ | C'est assez touffu je suis d' | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===== Tests de définition===== | ||
+ | |||
+ | Pour tester si une variable est non définie : '' | ||
+ | <code bash> | ||
+ | unset VAR | ||
+ | ${VAR?var non def} # -bash: VAR: variable non def (sur stderr) | ||
+ | declare VAR | ||
+ | ${VAR?var non def} # -bash: VAR: variable non def (sur stderr) | ||
+ | VAR= | ||
+ | ${VAR?var non def} # (rien car VAR est définie) | ||
+ | ${VAR:? | ||
+ | </ | ||
+ | |||
+ | Pour utiliser une valeur par défaut au cas ou la variable n'est pas définie : '' | ||
+ | <code bash> | ||
+ | declare VAR | ||
+ | echo ${VAR-defaut} | ||
+ | echo ${VAR: | ||
+ | |||
+ | unset VAR | ||
+ | echo ${VAR-defaut} | ||
+ | echo ${VAR: | ||
+ | </ | ||
+ | |||
+ | Cela ne définit ni n' | ||
+ | <code bash> | ||
+ | declare VAR | ||
+ | echo ${VAR=defaut} | ||
+ | echo ${VAR: | ||
+ | </ | ||
+ | |||
+ | =====Typage===== | ||
+ | |||
+ | Il n'y a pas de typage strict en bash, toutes les variables sont considérées comme des chaînes de caractères, | ||
+ | |||
+ | Pour " | ||
+ | <code bash> | ||
+ | is_ready=true | ||
+ | if [ " | ||
+ | then echo " | ||
+ | else echo " | ||
+ | fi | ||
+ | </ | ||
+ | |||
+ | Pour plus de détails sur le pseudo-typage en bash, voir la fonction [[informatique: | ||
+ | |||
+ | ===== Manipulation des variables===== | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | <code bash> | ||
+ | scp user@server:/ | ||
+ | </ | ||
+ | Sans les '' | ||
+ | * on peut tronquer une variable : '' | ||
+ | * '' | ||
+ | * Si on omet POS : '' | ||
+ | <code bash> | ||
+ | VAR=undeuxtroisquatre | ||
+ | echo ${VAR: | ||
+ | echo ${VAR: | ||
+ | echo ${VAR: | ||
+ | echo ${VAR:: | ||
+ | echo ${VAR:: | ||
+ | </ | ||
+ | |||
+ | On peut utiliser des motifs (qui en ont l' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * On peut limiter le remplacement aux seuls préfixe '' | ||
+ | <code bash> | ||
+ | VAR=undeuxtroisquatre | ||
+ | echo ${VAR# | ||
+ | echo ${VAR## | ||
+ | echo ${VAR%u*e} | ||
+ | echo ${VAR/ | ||
+ | echo ${VAR// | ||
+ | echo ${VAR/# | ||
+ | echo ${VAR/ | ||
+ | </ | ||
+ | |||
+ | Exemple usuels : | ||
+ | * sélectionner l' | ||
+ | * sélectionner le nom d'un fichier sans son extension : '' | ||
+ | * supprimer le dernier caractère de la variable (trim) : '' | ||
+ | |||
+ | source : https:// | ||
+ | |||
+ | =====Variables spécifiques===== | ||
Ce sont des variables liées au contexte du script. | Ce sont des variables liées au contexte du script. | ||
- | * '' | + | * '' |
- | * '' | + | * '' |
- | * '' | + | * '' |
+ | * '' | ||
+ | * '' | ||
* '' | * '' | ||
- | * '' | + | * '' |
- | * '' | + | * '' |
* '' | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
- | ===== Les variables | + | =====Les |
- | * '' | + | Les enregistrements commencent à l'index 0. Ainsi pour récupérer |
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
- | =====Les fonctions===== | + | Comme pour les variables classiques, on peut récupérer la longueur en le précèdent de ''#'' |
+ | * longueur de la 3e case : '' | ||
+ | * taille du tableau (nombre de case de celui-ci) : '' | ||
- | ==== read ==== | + | Pour parcourir facilement un tableau dans une boucle : |
- | '' | + | <code bash> |
+ | ARRAY=( un deux trois ) | ||
+ | for i in " | ||
+ | un | ||
+ | deux | ||
+ | trois | ||
+ | </ | ||
+ | Exemple de découpage d'une chaîne dans un tableau, avec comme séparateur ";" | ||
+ | <code bash> | ||
+ | CHAINE=' | ||
+ | IFS=";" | ||
+ | read -a TAB <<<" | ||
+ | echo " | ||
+ | 3 | ||
+ | printf ' | ||
+ | 17 | ||
+ | 8 23 | ||
+ | 9 | ||
+ | </ | ||
- | ===== Expressions arithmétiques ===== | + | ====Tableau à 2 dimensions==== |
+ | |||
+ | Ça n'eût pas existé sous bash :). Mais on peut l' | ||
+ | <code bash> | ||
+ | # déclaration d'un tableau associatif T | ||
+ | declare -A T | ||
+ | # remplissage clé => valeur, par exemple la clé " | ||
+ | # c'est un tableau à une dimension | ||
+ | T[0: | ||
+ | T[0: | ||
+ | T[1: | ||
+ | T[1: | ||
+ | T[2: | ||
+ | T[2: | ||
+ | |||
+ | # calcul de l' | ||
+ | T_SIZE=$((${# | ||
+ | |||
+ | # en forgeant la clé, on émule un tableau bidimensionnel : | ||
+ | for ((i=0; | ||
+ | echo " | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | ====Tableau associatif==== | ||
+ | |||
+ | Créer et utiliser un vrai tableau associatif : | ||
+ | <code bash> | ||
+ | declare -A TA=([cle1]=valeur1 ["cle 2" | ||
+ | echo " | ||
+ | # valeur1 | ||
+ | |||
+ | # Parcourir le tableau | ||
+ | for cle in " | ||
+ | echo " | ||
+ | done | ||
+ | #cle=cle 2 ; val=valeur 2 | ||
+ | #cle=cle3 ; val=valeur3 | ||
+ | #cle=cle1 ; val=valeur1 | ||
+ | </ | ||
+ | |||
+ | Pour connaitre la taille de ce tableau : '' | ||
+ | =====getopts : analyse des arguments d'un script===== | ||
+ | |||
+ | Cette commande permet de récupérer facilement les options (paramètres) avec lesquels a été lancé un script. Une option est un caractère précédé d'un + ou d'un - (à la différence d'un argument qui est " | ||
+ | Exemple d' | ||
+ | <code bash> | ||
+ | while getopts " | ||
+ | do | ||
+ | echo " | ||
+ | case $opt in | ||
+ | a) | ||
+ | echo "-a trouvée !" | ||
+ | echo " | ||
+ | ;; | ||
+ | b) | ||
+ | echo "-b trouvée ! son paramètre est : $OPTARG" | ||
+ | echo " | ||
+ | ;; | ||
+ | esac | ||
+ | done | ||
+ | </ | ||
+ | * $opt est le nom (arbitraire) de la variable recevant la valeur de l' | ||
+ | * ":" | ||
+ | * OPTIND est la variable réservée qui contient l' | ||
+ | * OPTARG est la variable réservée qui contient l' | ||
+ | |||
+ | La même option peut apparaitre plusieurs fois sans générer d' | ||
+ | Une option non attendue génèrera une erreur (non bloquante) et prendra la valeur "?" | ||
+ | Une option nécessitant un argument non présent génèrera aussi une erreur non bloquante, mais prendra la valeur ":" | ||
+ | |||
+ | On peut choisir de traiter les erreurs dans le script en préfixant la liste des options par un ":" | ||
+ | * dans le cas d'une option non attendue : | ||
+ | * $opt prend la valeur "?" | ||
+ | * $OPTARG prendra le nom de l' | ||
+ | * dans le cas d'une option nécessitant un argument non présent : | ||
+ | * $opt prendra la valeur ":" | ||
+ | * $OPTARG prend la valeur de l' | ||
+ | |||
+ | Reprise de l' | ||
+ | <code bash> | ||
+ | echo "### Liste des arguments = $*" | ||
+ | while getopts ": | ||
+ | do | ||
+ | echo " | ||
+ | case $opt in | ||
+ | a) | ||
+ | echo "-a trouvée !" | ||
+ | echo " | ||
+ | ;; | ||
+ | b) | ||
+ | echo "-b trouvée ! son paramètre est : $OPTARG" | ||
+ | echo " | ||
+ | ;; | ||
+ | c) | ||
+ | echo "-c trouvée ! son paramètre est : $OPTARG" | ||
+ | echo " | ||
+ | ;; | ||
+ | \?) # on doit échapper "?" | ||
+ | echo " | ||
+ | ;; | ||
+ | :) # ceci n'est pas un smiley | ||
+ | echo " | ||
+ | ;; | ||
+ | esac | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | Pour récupérer les éventuels arguments restants, on utilise la commande '' | ||
+ | <code bash> | ||
+ | shift $(($OPTIND-1)) # on supprime les options déjà traitées | ||
+ | |||
+ | echo "### Liste des arguments restants : $*" | ||
+ | while [ -n " | ||
+ | do | ||
+ | echo " | ||
+ | shift 1 | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | |||
+ | ======Descripteurs de fichier====== | ||
+ | |||
+ | Il existe 3 descripteurs de fichier standards, utilisés par toutes les commandes : 0, 1 et 2 correspondants à STDIN, STDOUT et STDERR (input, output et erreur). 0 pointe par défaut sur le clavier, 1 et 2 sont affichés par défaut à l' | ||
+ | |||
+ | Pour lire depuis un fichier plutôt que depuis le clavier : | ||
+ | <code bash> | ||
+ | echo toto > / | ||
+ | read VAR < / | ||
+ | echo $VAR | ||
+ | | ||
+ | </ | ||
+ | |||
+ | ====Les redirecteurs==== | ||
+ | |||
+ | * ''>'' | ||
+ | * ''< | ||
+ | * ''&> | ||
+ | * ''<'' | ||
+ | |||
+ | Ces redirecteurs sont restaurés à leur valeur par défaut à chaque nouvelle ligne ; en revanche tous les processus fils héritent des descripteurs de leur processus père, à moins que celui-ci ne les ferme (voir plus bas). | ||
+ | |||
+ | '' | ||
+ | |||
+ | Pour rediriger le flux d' | ||
+ | <code bash> | ||
+ | ./prog 2>/ | ||
+ | </ | ||
+ | |||
+ | Pour rediriger le flux d' | ||
+ | <code bash> | ||
+ | ./prog 2>&1 | ./ | ||
+ | # équivaut à | ||
+ | ./prog |& ./prog2 | ||
+ | # (depuis bash4, " | ||
+ | </ | ||
+ | |||
+ | |||
+ | Par défaut ''>'' | ||
+ | <code bash> | ||
+ | ./prog 2>>/ | ||
+ | </ | ||
+ | Ainsi on conserve les erreurs de chaque exécution du programme. | ||
+ | |||
+ | ====Heredoc==== | ||
+ | |||
+ | Un document " | ||
+ | <code bash> | ||
+ | cat << EOF | ||
+ | Ce | ||
+ | sera affiché tel quel | ||
+ | EOF | ||
+ | |||
+ | </ | ||
+ | |||
+ | On peut utiliser la variante ''< | ||
+ | |||
+ | ====Herestring==== | ||
+ | |||
+ | Dans la même veine que le heredoc, la herestring permet d' | ||
+ | <code bash> | ||
+ | VAR=" | ||
+ | cat <<< | ||
+ | dad text | ||
+ | |||
+ | bc <<< | ||
+ | 4 | ||
+ | </ | ||
+ | ====Descripteurs de fichier additionnels==== | ||
+ | |||
+ | On peut utiliser les descripteurs 3 et plus également, en les initialisant pour ne pas générer d' | ||
+ | <code bash> | ||
+ | echo " | ||
+ | echo " | ||
+ | | ||
+ | </ | ||
+ | |||
+ | Pour fermer un descripteur de fichier (le 3 par ex) : '' | ||
+ | |||
+ | On peut faire pointer un descripteur vers un fichier du système : | ||
+ | <code bash> | ||
+ | exec 3<> / | ||
+ | echo toto >& | ||
+ | exec 3>& | ||
+ | </ | ||
+ | |||
+ | Exemple d' | ||
+ | <code bash> | ||
+ | # An application of this is writing at a specified place in a file. | ||
+ | echo 1234567890 > File # Write string to " | ||
+ | exec 3<> File # Open " | ||
+ | read -n 4 <& | ||
+ | echo -n . >& | ||
+ | exec 3>& | ||
+ | cat File # ==> 1234.67890 | ||
+ | </ | ||
+ | |||
+ | ======Les fonctions====== | ||
+ | |||
+ | =====pipe (" | ||
+ | |||
+ | Le pipe (tube) est une fonction qui permet de chainer la sortie d'une première commande sur l' | ||
+ | <code bash> | ||
+ | echo "toto et tata" | awk ' | ||
+ | | ||
+ | </ | ||
+ | |||
+ | Le soucis c'est qu'on ne récupère que le code de retour de la dernière commande du pipe ; et dans l' | ||
+ | * récupérer les codes de retour de chaque commande dans le tableau '' | ||
+ | <code bash> | ||
+ | false | true | ||
+ | echo " | ||
+ | 1 0 | ||
+ | </ | ||
+ | * utiliser la variable '' | ||
+ | <code bash> | ||
+ | $ false | true; echo $? | ||
+ | 0 | ||
+ | $ set -o pipefail | ||
+ | $ false | true; echo $? | ||
+ | 1 | ||
+ | </ | ||
+ | ===== read ===== | ||
+ | |||
+ | '' | ||
+ | |||
+ | Si aucune variable n'est précisée, la saisie sera enregistrée dans la variable $REPLY par défaut. | ||
+ | |||
+ | Pour afficher un texte avant la saisie on utilise '' | ||
+ | <code bash> | ||
+ | read -p "Quel est le numéro de ta CB ? Et le cryptogramme visuel de derrière ?" CARD_NUMBER CRYPTO | ||
+ | </ | ||
+ | |||
+ | Pour lire depuis un fichier : | ||
+ | <code bash> | ||
+ | read < fichier.txt | ||
+ | |||
+ | # c'est plutôt utilisé dans une boucle while, pour le lire ligne par ligne : | ||
+ | while read line; do | ||
+ | echo $line | ||
+ | done < fichier.txt | ||
+ | </ | ||
+ | |||
+ | Pour lire depuis une liste de fichiers : | ||
+ | <code bash> | ||
+ | while read line; do | ||
+ | echo $line | ||
+ | done < <(find . -name foo* -print0) | ||
+ | |||
+ | # équivalent à : | ||
+ | find . -name foo* -print0 | while read line; do | ||
+ | echo $line | ||
+ | done | ||
+ | </ | ||
+ | Le premier exemple utilise une [[https:// | ||
+ | |||
+ | * : en réalité bash utilise réellement un fichier temporaire, la preuve : | ||
+ | <code bash> | ||
+ | $ echo <(echo foo) | ||
+ | / | ||
+ | |||
+ | $ cat <(echo foo) | ||
+ | foo | ||
+ | |||
+ | $ xargs echo < <(echo foo) | ||
+ | foo | ||
+ | </ | ||
+ | |||
+ | Pour lire depuis une variable : | ||
+ | <code bash> | ||
+ | read <<< | ||
+ | </ | ||
+ | ====== Expressions arithmétiques | ||
Pour faire un calcul il faut l' | Pour faire un calcul il faut l' | ||
Line 40: | Line 516: | ||
Pour incrémenter une variable : plusieurs possibilités : | Pour incrémenter une variable : plusieurs possibilités : | ||
- | * '' | + | * '' |
- | * ''< | + | * ''< |
- | * ''< | + | |
* ''< | * ''< | ||
- | ===== Instructions conditionnelles | + | ======Conversions====== |
- | ==== if ==== | + | Convertir $VAR_HEXA de l' |
+ | <code bash> | ||
+ | VAR_DECIMAL=$((16# | ||
+ | # ou, avec la commande let | ||
+ | let VAR_DECIMAL=0x$VAR_HEXA | ||
+ | </ | ||
- | < | + | |
+ | ====== Instructions conditionnelles ====== | ||
+ | |||
+ | =====if===== | ||
+ | |||
+ | < | ||
test expr | test expr | ||
</ | </ | ||
ou | ou | ||
- | < | + | < |
if [ expr ] | if [ expr ] | ||
then | then | ||
Line 62: | Line 547: | ||
</ | </ | ||
- | Exemple sur une seule ligne (//-n// renvoie TRUE si la chaine n'est pas vide) : | + | * Exemple sur une seule ligne (//-n// renvoie TRUE si la chaine n'est pas vide) : |
- | < | + | < |
if [ -n "" | if [ -n "" | ||
0 | 0 | ||
</ | </ | ||
- | === Expression sur les fichiers | + | ====Conditions multiples==== |
- | | + | Pour tester des conditions multiples, on doit encadrer les tests avec un double crochet : |
- | * '' | + | <code bash> |
+ | if [[ TRUE && TRUE || FALSE ]] | ||
+ | then | ||
+ | | ||
+ | else | ||
+ | echo "TRUE QUAND MÊME !" | ||
+ | fi | ||
+ | </code> | ||
+ | |||
+ | On peut également procéder ainsi : | ||
+ | <code bash> | ||
+ | if [ TRUE ] && [ TRUE ] || [ FALSE ] | ||
+ | </ | ||
+ | |||
+ | Les conditions multiples sans parenthèses sont lues dans l'ordre d'apparition (de gauche à droite), ici cela équivaut à : '' | ||
+ | |||
+ | * Structure avec " | ||
+ | <code bash> | ||
+ | if [ expr ] | ||
+ | then | ||
+ | elif | ||
+ | then | ||
+ | elif | ||
+ | then | ||
+ | [..] | ||
+ | else | ||
+ | fi | ||
+ | </ | ||
+ | |||
+ | ====Expression sur les fichiers==== | ||
* '' | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
* '' | * '' | ||
* '' | * '' | ||
* '' | * '' | ||
- | * '' | + | * '' |
+ | * '' | ||
+ | * '' | ||
- | === Chaînes de caractères === | + | ====Chaînes de caractères==== |
- | * '' | + | * '' |
- | * '' | + | * '' |
+ | * ''" | ||
+ | <code bash> | ||
+ | [[ "la réponse est 42" =~ ^.*([0-9]{2}).*$ ]] && echo " | ||
+ | 42 est la réponse | ||
+ | </ | ||
* '' | * '' | ||
* '' | * '' | ||
- | === Nombres, comparaison === | + | ==== Nombres, comparaison |
* '' | * '' | ||
* '' | * '' | ||
Line 91: | Line 616: | ||
* '' | * '' | ||
- | === Opérateurs === | + | Comme il n'y a pas de typage en bash, pour tester si la valeur d'une variable est un nombre (entier) il faut réaliser le tester : |
+ | <code bash> | ||
+ | # Solution à base de REGEX | ||
+ | [[ $VAR =~ ^[0-9]+$ ]] || echo "VAR n'est pas un entier" | ||
+ | # NB : l' | ||
+ | # ou doit être enregistrée dans une variable sinon ça ne matche pas | ||
+ | |||
+ | # " | ||
+ | [ $VAR -eq $VAR ] 2>/ | ||
+ | </ | ||
+ | ==== Opérateurs | ||
* '' | * '' | ||
* '' | * '' | ||
Line 99: | Line 634: | ||
- | ==== case ==== | + | ===== case ===== |
- | Test plusieurs | + | Test plusieurs |
+ | <code bash> | ||
+ | case < | ||
+ | | ||
+ | echo "motif 1" | ||
+ | echo " | ||
+ | ;; | ||
+ | | ||
+ | echo "motif 2 ou motif 3" | ||
+ | ;; | ||
+ | | ||
+ | echo "tous les autres motifs" | ||
+ | ;; | ||
+ | *) | ||
+ | echo "Tout le reste" | ||
+ | ;; | ||
+ | esac | ||
+ | </ | ||
- | case < | ||
- | | ||
- | | ||
- | .. | ||
- | esac | ||
+ | ===== for ===== | ||
- | ==== for ==== | + | Permet de créer une boucle déterministe : pour chaque valeur de i, on exécute la boucle. |
Exemples : | Exemples : | ||
- | + | < | |
- | < | + | |
for (( i = 1; i <= 5; i++ )) | for (( i = 1; i <= 5; i++ )) | ||
do | do | ||
- | echo $i | + | echo -n "$i " |
done | done | ||
</ | </ | ||
+ | Affichera : '' | ||
+ | Cela équivaut à : '' | ||
+ | <code bash> | ||
+ | DEBUT=1 | ||
+ | FIN=5 | ||
+ | # ne fonctionne pas : for i in {$DEBUT..$FIN} | ||
+ | # fonctionne : | ||
+ | for (( i = $DEBUT; i <= $FIN; i++ )) | ||
+ | </ | ||
+ | |||
+ | On peut spécifier l' | ||
+ | |||
+ | On peut aussi lui fournir une liste de mots : | ||
+ | <code bash> | ||
+ | for i in serveur1 serveur2 serveur3 | ||
+ | do | ||
+ | ssh $i " | ||
+ | done | ||
+ | </ | ||
- | Ou en une seule ligne de commande : | + | On peut l' |
- | < | + | < |
for i in serveur1 serveur2 serveur3; do ssh $i " | for i in serveur1 serveur2 serveur3; do ssh $i " | ||
</ | </ | ||
- | =====Divers===== | + | ====break==== |
+ | Pour sortir prématurément d'une boucle for, **while** ou **repeat**, on utilise le mot-clé **break** : | ||
+ | <code bash> | ||
+ | for i in {1..5} | ||
+ | do | ||
+ | if [ $i -eq 3 ] | ||
+ | | ||
+ | echo " | ||
+ | break | ||
+ | fi | ||
+ | echo $i | ||
+ | done | ||
+ | </ | ||
- | ====en vrac==== | + | Ce qui donne : |
+ | <code bash> | ||
+ | 1 | ||
+ | 2 | ||
+ | Huston nous avons un probleme ! | ||
+ | </ | ||
- | * lire un fichier ligne par ligne | + | ====continue==== |
- | < | + | Pour sortir de l' |
+ | <code bash> | ||
+ | for i in {1..5} | ||
+ | do | ||
+ | | ||
+ | | ||
+ | echo " | ||
+ | continue | ||
+ | fi | ||
+ | echo $i | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | Ce qui donne : | ||
+ | <code bash> | ||
+ | 1 | ||
+ | 2 | ||
+ | Huston nous avons un probleme ! | ||
+ | 4 | ||
+ | 5 | ||
+ | </ | ||
+ | |||
+ | =====while===== | ||
+ | |||
+ | Exécute la boucle tant que la condition suivant l' | ||
+ | |||
+ | exemple : compter de 1 à 5... | ||
+ | <code bash> | ||
+ | cpt=1 | ||
+ | while [ $cpt -le 5 ]; do | ||
+ | echo $cpt | ||
+ | (( cpt++ )) | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | exemple2 : lire un fichier ligne par ligne | ||
+ | < | ||
while read line | while read line | ||
do | do | ||
echo $line | echo $line | ||
- | done < fic.txt</ | + | done < fic.txt |
+ | </ | ||
+ | |||
+ | La même mais avec la sortie d'une commande : | ||
+ | <code bash> | ||
+ | cat fic.txt | while read line | ||
+ | do | ||
+ | echo $line | ||
+ | done | ||
+ | </ | ||
ou sur une seule ligne : | ou sur une seule ligne : | ||
- | < | + | < |
- | * commande rsh | + | =====until===== |
- | rsh -4 -n $serveur $commande | + | Exécute la boucle jusqu' |
+ | <code bash> | ||
+ | until < | ||
+ | do | ||
+ | echo " | ||
+ | done | ||
+ | </code> | ||
- | * commande ping limitée à 3 envois avec un timeout de 0.05s | + | =====select===== |
- | | + | Permet de créer un menu interactif, c'est à dire une saisie utilisateur ; |
- | retour=$? | + | * $PS3 permet de définir le prompt |
+ | * $REPLY contient l' | ||
+ | |||
+ | <code bash> | ||
+ | PS3=" | ||
+ | select i in {2..5} | ||
+ | do | ||
+ | # $REPLY contient l' | ||
+ | # $i contient la valeur correspondante | ||
+ | echo $REPLY-$i | ||
+ | |||
+ | # pour sortir du menu (car il s'agit d'une boucle) | ||
+ | break | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | |||
+ | ======Divers====== | ||
+ | |||
+ | =====debug===== | ||
+ | |||
+ | Pour débugger un script, on insère en début de script la commande '' | ||
+ | ====en vrac==== | ||
+ | |||
+ | * commande rsh | ||
+ | <code bash> | ||
+ | rsh -4 -n $serveur $commande >/ | ||
+ | </ | ||
+ | |||
+ | * commande ping limitée à 3 envois avec un timeout de 0.05s | ||
+ | <code bash> | ||
+ | ping -c3 -w 0.05 soekris-${cpt} >/ | ||
+ | retour=$? | ||
+ | </ | ||
* attente d'un '' | * attente d'un '' | ||
+ | <code bash> | ||
+ | trap "echo ' | ||
+ | </ | ||
- | trap "echo ' | + | ===== Substitution de chaine ===== |
- | ==== Substitution de chaine ==== | ||
Pour n' | Pour n' | ||
- | L' | + | L'//offset//, c'est l' |
- | Par exemple pour afficher la sous-chaine " | + | |
- | test="titi tata toto" | + | Par exemple : |
- | echo ${test:5:4} | + | <code bash> |
+ | TEST="Je suis chanceux" | ||
- | (on affiche | + | # on affiche |
+ | echo ${TEST:3} | ||
+ | suis chanceux | ||
- | ==== Remplacement de chaine ==== | + | # idem, mais on se limite à 4 caractères affichés : |
- | Pour remplacer " | + | echo ${TEST:3:4} |
+ | suis | ||
- | test="titi tata toto" | + | # on peut spécifier un offset négatif pour compter l' |
- | echo ${test// | + | # cependant il faudra ajouter un espace avant le "-" |
- | titi tata tata | + | echo ${TEST: -8} |
+ | chanceux | ||
+ | echo ${TEST: | ||
+ | chanceux | ||
+ | </ | ||
- | notez bien le double slash (/). | + | ===== Remplacement de chaine ===== |
+ | Syntaxe : '' | ||
+ | |||
+ | //< | ||
+ | |||
+ | //< | ||
+ | * ''/'' | ||
+ | * ''#'' | ||
+ | * '' | ||
+ | |||
+ | <code bash> | ||
+ | TEST=" | ||
+ | |||
+ | # remplacer tous les " | ||
+ | echo ${TEST// | ||
+ | toto titi titi | ||
+ | |||
+ | # ne remplacer que " | ||
+ | echo ${TEST/ | ||
+ | toto titi tati | ||
+ | |||
+ | # ne remplacer que le premier " | ||
+ | echo ${TEST/# | ||
+ | poto titi tata | ||
+ | </ | ||
+ | |||
+ | =====Modifier la casse===== | ||
+ | |||
+ | Pour modifier la casse, on utilise la syntaxe : | ||
+ | * '' | ||
+ | * ou '' | ||
+ | |||
+ | //< | ||
+ | <code bash> | ||
+ | TEST=" | ||
+ | |||
+ | echo ${TEST^} | ||
+ | Toto TITI tata | ||
+ | </ | ||
+ | |||
+ | On peut doubler les lettres pour traiter toute la chaine de caractère : | ||
+ | <code bash> | ||
+ | echo ${TEST^^} | ||
+ | TOTO TITI TATA | ||
+ | |||
+ | echo ${TEST,,} | ||
+ | toto titi tata | ||
+ | </ | ||
+ | |||
+ | Enfin, on peut spécifier la pattern à la suite : | ||
+ | <code bash> | ||
+ | # on UPPERCASE tous les " | ||
+ | echo ${TEST^^t} | ||
+ | ToTo TITI TaTa | ||
+ | |||
+ | # on UPPERCASE les " | ||
+ | echo ${TEST^^[ta]} | ||
+ | ToTo TITI TATA | ||
+ | </ | ||
+ | |||
+ | =====Préfixes et suffixes===== | ||
+ | |||
+ | Syntaxe : '' | ||
+ | |||
+ | On s'en sert souvent pour manipuler les chemins et les noms de fichier : | ||
+ | <code bash> | ||
+ | FIC=/ | ||
+ | |||
+ | # afficher uniquement son extension | ||
+ | # (on supprime le plus long préfixe se terminant par " | ||
+ | echo ${FIC##*.} | ||
+ | fichier.ext | ||
+ | |||
+ | # afficher le chemin du fichier : | ||
+ | # (on supprime le suffixe le plus court contenant un "/" | ||
+ | echo ${FIC%/*} | ||
+ | / | ||
+ | </ | ||
- | ===== Liens ===== | + | ====== Ressources ====== |
* http:// | * http:// | ||
* http:// | * http:// | ||
* [[http:// | * [[http:// | ||
+ | * https:// | ||
+ | * [[https:// |
informatique/linux/programmation_shell.txt · Last modified: 2023/10/02 13:35 by pteu