Bash
Structures de contrôle
Recherche…
Syntaxe
- ["$ 1" = "$ 2"] #Un "[" crochet est en fait une commande. Pour cela, il faut un espace avant et après.
- test "$ 1" = "$ 2" #Test un synonyme de la commande "["
Paramètres
Paramètre à [ou test | Détails |
---|---|
Opérateurs de fichiers | Détails |
-e "$file" | Renvoie true si le fichier existe |
-d "$file" | Renvoie true si le fichier existe et est un répertoire |
-f "$file" | Renvoie true si le fichier existe et est un fichier normal |
-h "$file" | Renvoie true si le fichier existe et constitue un lien symbolique |
Comparateurs de chaînes | Détails |
-z "$str" | Vrai si la longueur de la chaîne est zéro |
-n "$str | Vrai si la longueur de la chaîne est différente de zéro |
"$str" = "$str2" | True si string $ str est égal à string $ str2. Pas le meilleur pour les entiers. Cela peut fonctionner mais sera inconsistant |
"$str" != "$str2" | Vrai si les chaînes ne sont pas égales |
Comparateurs entiers | Détails |
"$int1" -eq "$int2" | Vrai si les entiers sont égaux |
"$int1" -ne "$int2" | Vrai si les entiers ne sont pas égaux |
"$int1" -gt "$int2" | True si int1 est supérieur à int 2 |
"$int1" -ge "$int2" | True si int1 est supérieur ou égal à int2 |
"$int1" -lt "$int2" | True si int1 est inférieur à int 2 |
"$int1" -le "$int2" | True si int1 est inférieur ou égal à int2 |
Remarques
De nombreux paramètres de comparaison sont disponibles dans bash. Tous ne sont pas encore listés ici.
Si déclaration
if [[ $1 -eq 1 ]]; then
echo "1 was passed in the first parameter"
elif [[ $1 -gt 2 ]]; then
echo "2 was not passed in the first parameter"
else
echo "The first parameter was not 1 and is not more than 2."
fi
La fermeture fi
est nécessaire, mais les clauses elif
et / ou else
peuvent être omises.
Les virgules avant then
sont syntaxe standard pour combiner deux commandes sur une seule ligne; ils peuvent être omis que si then
est déplacé à la ligne suivante.
Il est important de comprendre que les crochets [[
ne font pas partie de la syntaxe, mais sont traités comme une commande; c'est le code de sortie de cette commande qui est en cours de test. Par conséquent, vous devez toujours inclure des espaces entre les crochets.
Cela signifie également que le résultat de toute commande peut être testé. Si le code de sortie de la commande est un zéro, l'instruction est considérée comme vraie.
if grep "foo" bar.txt; then
echo "foo was found"
else
echo "foo was not found"
fi
Les expressions mathématiques, lorsqu'elles sont placées à l'intérieur de doubles parenthèses, renvoient également 0 ou 1 de la même manière et peuvent également être testées:
if (( $1 + 5 > 91 )); then
echo "$1 is greater than 86"
fi
Vous pouvez également rencontrer if
les déclarations avec crochets simples. Ceux-ci sont définis dans la norme POSIX et sont garantis pour fonctionner dans tous les shells compatibles POSIX, y compris Bash. La syntaxe est très similaire à celle de Bash:
if [ "$1" -eq 1 ]; then
echo "1 was passed in the first parameter"
elif [ "$1" -gt 2 ]; then
echo "2 was not passed in the first parameter"
else
echo "The first parameter was not 1 and is not more than 2."
fi
En boucle
#! /bin/bash
i=0
while [ $i -lt 5 ] #While i is less than 5
do
echo "i is currently $i"
i=$[$i+1] #Not the lack of spaces around the brackets. This makes it a not a test expression
done #ends the loop
Veillez à ce qu'il y ait des espaces autour des parenthèses pendant le test (après la déclaration while). Ces espaces sont nécessaires.
Cette boucle de sortie:
i is currently 0
i is currently 1
i is currently 2
i is currently 3
i is currently 4
Pour boucle
#! /bin/bash
for i in 1 "test" 3; do #Each space separated statement is assigned to i
echo $i
done
D'autres commandes peuvent générer des instructions à boucler. Voir "Utilisation de la boucle pour itérer les nombres".
Cela produit:
1
test
3
Utilisation de la boucle For pour répertorier les itérations sur les nombres
#! /bin/bash
for i in {1..10}; do # {1..10} expands to "1 2 3 4 5 6 7 8 9 10"
echo $i
done
Cela génère les éléments suivants:
1
2
3
4
5
6
7
8
8
10
Pour une boucle avec une syntaxe de style C
Le format de base du style C for
boucle est le suivant:
for (( variable assignment; condition; iteration process ))
Remarques:
- L'affectation de la variable à l'intérieur du style C
for
boucle peut contenir des espaces contrairement à l'attribution habituelle - Les variables de style C
for
boucle ne sont pas précédées de$
.
Exemple:
for (( i = 0; i < 10; i++ ))
do
echo "The iteration number is $i"
done
Nous pouvons également traiter plusieurs variables dans le style C for
boucle:
for (( i = 0, j = 0; i < 10; i++, j = i * i ))
do
echo "The square of $i is equal to $j"
done
Jusqu'à la boucle
Jusqu'à ce que la boucle s'exécute jusqu'à ce que la condition soit vraie
i=5
until [[ i -eq 10 ]]; do #Checks if i=10
echo "i=$i" #Print the value of i
i=$((i+1)) #Increment i by 1
done
Sortie:
i=5
i=6
i=7
i=8
i=9
Quand i
atteint 10 l'état jusqu'à ce que la boucle devient vraie et la fin de la boucle.
continuer et casser
Exemple pour continuer
for i in [series]
do
command 1
command 2
if (condition) # Condition to jump over command 3
continue # skip to the next value in "series"
fi
command 3
done
Exemple de pause
for i in [series]
do
command 4
if (condition) # Condition to break the loop
then
command 5 # Command if the loop needs to be broken
break
fi
command 6 # Command to run if the "condition" is never true
done
En boucle sur un tableau
for
boucle:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
done
Ou
for ((i=0;i<${#arr[@]};i++));do
echo "${arr[$i]}"
done
while
boucle:
i=0
while [ $i -lt ${#arr[@]} ];do
echo "${arr[$i]}"
i=$(expr $i + 1)
done
Ou
i=0
while (( $i < ${#arr[@]} ));do
echo "${arr[$i]}"
((i++))
done
Pause de boucle
Casser plusieurs boucles:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break 2
done
done
Sortie:
a
a
Casser une seule boucle:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break
done
done
Sortie:
a
a
b
a
c
a
d
a
e
a
f
a
Déclaration de changement de cas
Avec l'instruction case
, vous pouvez associer des valeurs à une variable.
L'argument transmis à case
est développé et tente de correspondre à chaque modèle.
Si une correspondance est trouvée, les commandes jusqu'à ;;
sont exécutés.
case "$BASH_VERSION" in
[34]*)
echo {1..4}
;;
*)
seq -s" " 1 4
esac
Les patterns ne sont pas des expressions régulières mais des correspondances de patterns de shell (aussi appelés globs).
Pour une boucle sans paramètre de liste de mots
for arg; do
echo arg=$arg
done
Une boucle for
sans paramètre de liste de mots parcourra les paramètres de position à la place. En d'autres termes, l'exemple ci-dessus est équivalent à ce code:
for arg in "$@"; do
echo arg=$arg
done
En d'autres termes, si vous vous surprenez à écrire for i in "$@"; do ...; done
, juste laisser tomber la in
une partie, et il suffit d' écrire for i; do ...; done
.
Exécution conditionnelle des listes de commandes
Comment utiliser l'exécution conditionnelle des listes de commandes
Toute commande, expression ou fonction intégrée, ainsi que toute commande ou script externe peuvent être exécutés de manière conditionnelle à l'aide des fonctions &&
(and) et ||
(ou) opérateurs.
Par exemple, cela imprimera uniquement le répertoire en cours si la commande cd
a réussi.
cd my_directory && pwd
De même, cela se terminera si la commande cd
échoue, empêchant une catastrophe:
cd my_directory || exit
rm -rf *
Lorsque vous combinez plusieurs instructions de cette manière, il est important de vous rappeler que (contrairement à de nombreux langages de style C) ces opérateurs n'ont pas de priorité et sont associés à gauche .
Ainsi, cette déclaration fonctionnera comme prévu ...
cd my_directory && pwd || echo "No such directory"
- Si le
cd
réussit, le&& pwd
s'exécute et le nom du répertoire de travail actuel est imprimé. A moins quepwd
échoue (une rareté) le|| echo ...
ne sera pas exécuté. - Si le
cd
échoue, le&& pwd
sera ignoré et le|| echo ...
va courir
Mais ce ne sera pas le cas (si vous pensez if...then...else
) ...
cd my_directory && ls || echo "No such directory"
- Si le
cd
échoue, le&& ls
est ignoré et le|| echo ...
est exécuté. - Si le
cd
réussit, le&& ls
est exécuté.- Si le
ls
réussit, le|| echo ...
est ignoré. (jusqu'ici tout va bien) - MAIS ... si le
ls
échoue, le|| echo ...
sera également exécuté.C'est le
ls
, pas lecd
, c'est la commande précédente .
- Si le
Pourquoi utiliser une exécution conditionnelle des listes de commandes
L'exécution conditionnelle est un cheveu plus rapide que if...then
mais son principal avantage est de permettre aux fonctions et aux scripts de sortir tôt, ou "court-circuit".
Contrairement à de nombreux langages tels que C
où la mémoire est explicitement allouée aux structs et aux variables, et donc (et doit donc être désallouée), bash
gère cela sous les couvertures. Dans la plupart des cas, nous n'avons rien à nettoyer avant de quitter la fonction. Une déclaration de return
désallouera tout ce qui est local à la fonction et l'exécution de la collecte à l'adresse de retour de la pile.
Le retour de fonctions ou la sortie de scripts dès que possible peut donc améliorer considérablement les performances et réduire la charge du système en évitant l'exécution inutile du code. Par exemple...
my_function () {
### ALWAYS CHECK THE RETURN CODE
# one argument required. "" evaluates to false(1)
[[ "$1" ]] || return 1
# work with the argument. exit on failure
do_something_with "$1" || return 1
do_something_else || return 1
# Success! no failures detected, or we wouldn't be here
return 0
}