Bash
Kontrollstrukturer
Sök…
Syntax
- ["$ 1" = "$ 2"] #A "[" konsol är faktiskt ett kommando. På grund av detta krävs det ett utrymme före och efter det.
- test "$ 1" = "$ 2" #Test är en synonym för kommandot "["
parametrar
Parameter till [eller test | detaljer |
---|---|
Filoperatörer | detaljer |
-e "$file" | Returnerar sant om filen finns. |
-d "$file" | Returnerar sant om filen finns och är en katalog |
-f "$file" | Returnerar sant om filen finns och är en vanlig fil |
-h "$file" | Returnerar sant om filen finns och är en symbolisk länk |
Strängkomparatorer | detaljer |
-z "$str" | Sant om längden på strängen är noll |
-n "$str | Sant om längden på strängen är icke-noll |
"$str" = "$str2" | Sant om strängen $ str är lika med strängen $ str2. Inte bäst för heltal. Det kan fungera men kommer att vara inkonsekvent |
"$str" != "$str2" | Det är sant om strängarna inte är lika |
Heltalskomparatorer | detaljer |
"$int1" -eq "$int2" | Det är sant om heltalet är lika |
"$int1" -ne "$int2" | Det är sant om heltalen inte är lika |
"$int1" -gt "$int2" | Det är sant om int1 är större än int 2 |
"$int1" -ge "$int2" | Det är sant om int1 är större än eller lika med int2 |
"$int1" -lt "$int2" | Det är sant om int1 är mindre än int 2 |
"$int1" -le "$int2" | Det är sant om int1 är mindre än eller lika med int2 |
Anmärkningar
Det finns många komparatorparametrar tillgängliga i bash. Inte alla är ännu listade här.
Om uttalande
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
Stängnings fi
är nödvändigt, men elif
och / eller else
klausulerna kan uteslutas.
Semikolon före then
är standardsyntax för att kombinera två kommandon på en enda rad; de kan utelämnas endast om de then
flyttas till nästa rad.
Det är viktigt att förstå att parenteserna [[
inte är en del av syntaxen utan behandlas som ett kommando; det är utgångskoden från det här kommandot som testas. Därför måste du alltid inkludera utrymmen runt parenteserna.
Detta betyder också att resultatet av vilket kommando som helst kan testas. Om utgångskoden från kommandot är noll betraktas uttalandet som sant.
if grep "foo" bar.txt; then
echo "foo was found"
else
echo "foo was not found"
fi
Matematiska uttryck, när de placeras i dubbla parenteser, returnerar också 0 eller 1 på samma sätt och kan också testas:
if (( $1 + 5 > 91 )); then
echo "$1 is greater than 86"
fi
Du kan också stöta på if
uttalanden med enstaka parenteser. Dessa definieras i POSIX-standarden och garanteras att de fungerar i alla POSIX-kompatibla skal inklusive Bash. Syntaxen är mycket lik den i 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
Medan Loop
#! /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
Se att det finns utrymmen runt parenteserna under testet (efter uttalandet medan). Dessa utrymmen är nödvändiga.
Denna slinga matar ut:
i is currently 0
i is currently 1
i is currently 2
i is currently 3
i is currently 4
För slinga
#! /bin/bash
for i in 1 "test" 3; do #Each space separated statement is assigned to i
echo $i
done
Andra kommandon kan generera uttalanden för att slinga över. Se exemplet "Använda för loop för att uppskatta siffror".
Denna utgångar:
1
test
3
Använd för loop för att lista över siffror
#! /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
Detta matar ut följande:
1
2
3
4
5
6
7
8
8
10
För slinga med syntax i C-stil
Grundformatet för C-stil for
loop är:
for (( variable assignment; condition; iteration process ))
Anmärkningar:
- Tilldelningen av variabeln inuti C-stil
for
loop kan innehålla mellanslag till skillnad från den vanliga tilldelningen - Variabler i C-stil
for
loop föregås inte med$
.
Exempel:
for (( i = 0; i < 10; i++ ))
do
echo "The iteration number is $i"
done
Vi kan också behandla flera variabler i C-stil for
loop:
for (( i = 0, j = 0; i < 10; i++, j = i * i ))
do
echo "The square of $i is equal to $j"
done
Tills Loop
Tills slingan körs tills villkoret är sant
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
Produktion:
i=5
i=6
i=7
i=8
i=9
När i
når 10 kommer villkoret in tills slingan blir sann och slingan slutar.
fortsätt och bryt
Exempel för fortsättning
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
Exempel för paus
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
Looping över en matris
for
slinga:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
done
Eller
for ((i=0;i<${#arr[@]};i++));do
echo "${arr[$i]}"
done
while
slinga:
i=0
while [ $i -lt ${#arr[@]} ];do
echo "${arr[$i]}"
i=$(expr $i + 1)
done
Eller
i=0
while (( $i < ${#arr[@]} ));do
echo "${arr[$i]}"
((i++))
done
Loop break
Bryt flera slingor:
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
Produktion:
a
a
Bryt en enda slinga:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break
done
done
Produktion:
a
a
b
a
c
a
d
a
e
a
f
a
Byt uttalande med ärende
Med case
du matcha värden mot en variabel.
Argumentet som överförts till case
utvidgas och försök matcha mot varje mönster.
Om en matchning hittas kommer kommandona upp ;;
avrättas.
case "$BASH_VERSION" in
[34]*)
echo {1..4}
;;
*)
seq -s" " 1 4
esac
Mönster är inte vanliga uttryck utan skalmatchning (aka globs).
För Loop utan en lista med ord-parameter
for arg; do
echo arg=$arg
done
En for
slinga utan en lista med ordparametrar itereras över positionsparametrarna istället. Med andra ord motsvarar exemplet ovan denna kod:
for arg in "$@"; do
echo arg=$arg
done
Med andra ord, om du fångar dig själv att skriva for i in "$@"; do ...; done
, bara släppa den in
sidan och skriva bara for i; do ...; done
.
Villkorligt utförande av kommandolistor
Hur man använder villkorlig körning av kommandolistor
Alla inbyggda kommandon, uttryck eller funktioner samt alla externa kommandon eller skript kan utföras villkorligt med &&
(och) och ||
(eller) operatörer.
Till exempel kommer detta bara att skriva ut den aktuella katalogen om cd
kommandot var framgångsrikt.
cd my_directory && pwd
På samma sätt kommer detta att avslutas om cd
kommandot misslyckas, vilket förhindrar katastrof:
cd my_directory || exit
rm -rf *
När man kombinerar flera uttalanden på detta sätt är det viktigt att komma ihåg att (till skillnad från många språk i C-stil) dessa operatörer inte har någon företräde och är vänsterassocierande .
Således kommer detta uttalande att fungera som förväntat ...
cd my_directory && pwd || echo "No such directory"
- Om
cd
lyckas körs&& pwd
och det aktuella katalognamnet skrivs ut. Om intepwd
misslyckas (en sällsynthet) kommer|| echo ...
kommer inte att köras. - Om
cd
misslyckas hoppas&& pwd
över och|| echo ...
kommer att köras.
Men detta kommer inte (om du tänker if...then...else
) ...
cd my_directory && ls || echo "No such directory"
- Om
cd
misslyckas, hoppas&& ls
över och|| echo ...
körs. - Om
cd
lyckas körs&& ls
.- Om
ls
lyckas,|| echo ...
ignoreras. (än så länge är allt bra) - MEN ... om
ls
misslyckas,|| echo ...
kommer också att köras.Det är
ls
, intecd
, som är det föregående kommandot .
- Om
Varför använda villkorlig körning av kommandolistor
Villkorligt utförande är ett hår snabbare än if...then
men dess huvudfördel är att funktioner och skript kan lämna tidigt, eller "kortslutning".
Till skillnad från många språk som C
där minnet uttryckligen allokeras för strukturer och variabler och sådant (och därmed måste omlokaliseras), hanterar bash
detta under omslagen. I de flesta fall behöver vi inte städa upp något innan vi lämnar funktionen. En return
uttalande kommer avallokera allt lokal funktion och pickup utförande vid returadressen i stacken.
Att återvända från funktioner eller lämna skript så snart som möjligt kan alltså förbättra prestandan betydligt och minska systembelastningen genom att undvika onödig körning av kod. Till exempel...
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
}