Bash
Besturingsstructuren
Zoeken…
Syntaxis
- ["$ 1" = "$ 2"] #A "[" bracket is eigenlijk een opdracht. Hierdoor heeft het een ruimte nodig voor en erna.
- test "$ 1" = "$ 2" #Test is een synoniem voor de opdracht "["
parameters
Parameter voor [of test | Details |
---|---|
Bestandsoperators | Details |
-e "$file" | Retourneert true als het bestand bestaat. |
-d "$file" | Retourneert true als het bestand bestaat en een map is |
-f "$file" | Retourneert true als het bestand bestaat en een normaal bestand is |
-h "$file" | Retourneert true als het bestand bestaat en een symbolische link is |
Stringvergelijkers | Details |
-z "$str" | Waar als de lengte van de string nul is |
-n "$str | Waar als de lengte van de reeks niet nul is |
"$str" = "$str2" | Waar als string $ str gelijk is aan string $ str2. Niet het beste voor gehele getallen. Het kan werken, maar zal onsamenhangend zijn |
"$str" != "$str2" | Waar als de tekenreeksen niet gelijk zijn |
Integer vergelijkers | Details |
"$int1" -eq "$int2" | Waar als de gehele getallen gelijk zijn |
"$int1" -ne "$int2" | Waar als de gehele getallen niet gelijk zijn |
"$int1" -gt "$int2" | Waar als int1 groter is dan int 2 |
"$int1" -ge "$int2" | Waar als int1 groter is dan of gelijk aan int2 |
"$int1" -lt "$int2" | Waar als int1 kleiner is dan int 2 |
"$int1" -le "$int2" | Waar als int1 kleiner is dan of gelijk aan int2 |
Opmerkingen
Er zijn veel vergelijkingsparameters beschikbaar in bash. Nog niet alle zijn hier vermeld.
Als verklaring
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
De afsluitende fi
is noodzakelijk, maar de elif
en / of de else
clausules kunnen worden weggelaten.
De puntkomma vóór then
zijn standaard syntax voor het combineren van twee commando's op een enkele lijn; ze kunnen alleen worden weggelaten als ze then
naar de volgende regel worden verplaatst.
Het is belangrijk om te begrijpen dat de haakjes [[
geen deel uitmaken van de syntaxis, maar worden behandeld als een opdracht; het is de exitcode van deze opdracht die wordt getest. Daarom moet u altijd spaties rond de haakjes opnemen.
Dit betekent ook dat het resultaat van een opdracht kan worden getest. Als de exitcode van de opdracht een nul is, wordt de instructie als waar beschouwd.
if grep "foo" bar.txt; then
echo "foo was found"
else
echo "foo was not found"
fi
Wiskundige uitdrukkingen, wanneer ze tussen dubbele haakjes worden geplaatst, retourneren ook 0 of 1 op dezelfde manier en kunnen ook worden getest:
if (( $1 + 5 > 91 )); then
echo "$1 is greater than 86"
fi
U kunt ook tegenkomen if
uitspraken met enkele haakjes. Deze zijn gedefinieerd in de POSIX-standaard en werken gegarandeerd in alle POSIX-compatibele shells inclusief Bash. De syntaxis lijkt erg op die in 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
Herhalingslus
#! /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
Let op dat er spaties rond de haakjes zijn tijdens de test (na de while-opdracht). Deze ruimtes zijn noodzakelijk.
Deze lus geeft uit:
i is currently 0
i is currently 1
i is currently 2
i is currently 3
i is currently 4
For loop
#! /bin/bash
for i in 1 "test" 3; do #Each space separated statement is assigned to i
echo $i
done
Andere opdrachten kunnen instructies genereren om te herhalen. Zie het voorbeeld "For Loop gebruiken om nummers te herhalen".
Dit geeft uit:
1
test
3
For Loop gebruiken om lijst te herhalen
#! /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
Dit levert het volgende op:
1
2
3
4
5
6
7
8
8
10
Voor lus met syntaxis in C-stijl
Het basisformaat van C-stijl for
lus is:
for (( variable assignment; condition; iteration process ))
Opmerkingen:
- De toewijzing van de variabele in C-stijl
for
lus kan spaties bevatten in tegenstelling tot de gebruikelijke toewijzing - Variabelen in C-stijl
for
lus worden niet voorafgegaan door$
.
Voorbeeld:
for (( i = 0; i < 10; i++ ))
do
echo "The iteration number is $i"
done
Ook kunnen we meerdere variabelen in C-stijl for
lus verwerken:
for (( i = 0, j = 0; i < 10; i++, j = i * i ))
do
echo "The square of $i is equal to $j"
done
Tot Loop
Tot lus wordt uitgevoerd totdat voorwaarde waar is
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
Output:
i=5
i=6
i=7
i=8
i=9
Wanneer i
10 bereik, wordt de voorwaarde ingevoerd totdat de lus waar wordt en de lus eindigt.
ga door en breek
Voorbeeld voor doorgaan
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
Voorbeeld voor pauze
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
Een lus doorlopen
for
lus:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
done
Of
for ((i=0;i<${#arr[@]};i++));do
echo "${arr[$i]}"
done
while
lus:
i=0
while [ $i -lt ${#arr[@]} ];do
echo "${arr[$i]}"
i=$(expr $i + 1)
done
Of
i=0
while (( $i < ${#arr[@]} ));do
echo "${arr[$i]}"
((i++))
done
Loop break
Breek meerdere lus:
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
Output:
a
a
Break enkele lus:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break
done
done
Output:
a
a
b
a
c
a
d
a
e
a
f
a
Schakel verklaring met geval
Met de case
kunt u waarden vergelijken met één variabele.
Het argument dat wordt doorgegeven aan case
wordt uitgebreid en probeert te matchen met elk patroon.
Als een overeenkomst wordt gevonden, kunt u met de opdrachten ;;
worden uitgevoerd.
case "$BASH_VERSION" in
[34]*)
echo {1..4}
;;
*)
seq -s" " 1 4
esac
Patroon zijn geen reguliere uitdrukkingen maar shell-patroonovereenkomst (aka globs).
Voor lus zonder een lijst met woorden
for arg; do
echo arg=$arg
done
Een for
lus zonder een lijst met woordenparameters zal in plaats daarvan de positionele parameters herhalen. Met andere woorden, het bovenstaande voorbeeld is gelijk aan deze code:
for arg in "$@"; do
echo arg=$arg
done
Met andere woorden, als je jezelf betrapt op het schrijven for i in "$@"; do ...; done
, maar stuur het in
deel, en gewoon schrijven for i; do ...; done
.
Voorwaardelijke uitvoering van opdrachtenlijsten
Voorwaardelijke uitvoering van opdrachtenlijsten gebruiken
Elke ingebouwde opdracht, expressie of functie, evenals elk extern commando of script kan voorwaardelijk worden uitgevoerd met de &&
(en) en ||
(of) exploitanten.
Dit zal bijvoorbeeld alleen de huidige map afdrukken als het cd
commando succesvol was.
cd my_directory && pwd
Evenzo wordt dit afgesloten als het cd
commando mislukt, waardoor catastrofe wordt voorkomen:
cd my_directory || exit
rm -rf *
Bij het combineren van meerdere statements op deze manier, is het belangrijk om te onthouden dat (in tegenstelling tot veel C-stijl talen) deze operatoren geen voorrang hebben en links-associatief zijn .
Deze verklaring werkt dus zoals verwacht ...
cd my_directory && pwd || echo "No such directory"
- Als de
cd
slaagt, wordt de&& pwd
uitgevoerd en wordt de naam van de huidige werkmap afgedrukt. Tenzijpwd
faalt (een zeldzaamheid) de|| echo ...
wordt niet uitgevoerd. - Als de
cd
faalt, wordt de&& pwd
overgeslagen en de|| echo ...
zal lopen.
Maar dit zal niet (als je denkt if...then...else
) ...
cd my_directory && ls || echo "No such directory"
- Als de
cd
mislukt, worden de&& ls
overgeslagen en de|| echo ...
wordt uitgevoerd. - Als de
cd
slaagt, wordt de&& ls
uitgevoerd.- Als de
ls
slaagt, de|| echo ...
wordt genegeerd. (tot nu toe zo goed) - MAAR ... als de
ls
faalt, de|| echo ...
wordt ook uitgevoerd.Het is de
ls
, niet decd
, dat is het vorige commando .
- Als de
Waarom voorwaardelijke uitvoering van opdrachtlijsten gebruiken
Voorwaardelijke uitvoering is een haar sneller dan if...then
maar het belangrijkste voordeel is dat functies en scripts vroegtijdig kunnen worden afgesloten, of "kortsluiting".
In tegenstelling tot veel talen zoals C
waar geheugen expliciet wordt toegewezen voor structs en variabelen en dergelijke (en dus moet worden toegewezen), behandelt bash
dit onder de covers. In de meeste gevallen hoeven we niets op te ruimen voordat we de functie verlaten. Een return
zal alles lokaal toewijzen aan de functie en de uitvoering van het ophalen op het retouradres op de stapel.
Terugkeren van functies of scripts zo snel mogelijk afsluiten kan dus de prestaties aanzienlijk verbeteren en de systeembelasting verminderen door onnodige uitvoering van code te voorkomen. Bijvoorbeeld...
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
}