Bash
Struktury kontrolne
Szukaj…
Składnia
- ["$ 1" = "$ 2"] #A "[" Nawias to tak naprawdę polecenie. Z tego powodu wymaga miejsca przed i po nim.
- test „$ 1” = „$ 2” #Test jest synonimem polecenia „[”
Parametry
Parametr do [lub test | Detale |
---|---|
Operatorzy plików | Detale |
-e "$file" | Zwraca true, jeśli plik istnieje. |
-d "$file" | Zwraca wartość true, jeśli plik istnieje i jest katalogiem |
-f "$file" | Zwraca true, jeśli plik istnieje i jest zwykłym plikiem |
-h "$file" | Zwraca true, jeśli plik istnieje i jest dowiązaniem symbolicznym |
Komparatory strunowe | Detale |
-z "$str" | Prawda, jeśli długość łańcucha wynosi zero |
-n "$str | Prawda, jeśli długość ciągu nie jest równa zero |
"$str" = "$str2" | Prawda, jeśli ciąg $ str jest równy ciągowi $ str2. Nie najlepiej dla liczb całkowitych. To może działać, ale będzie niespójne |
"$str" != "$str2" | Prawda, jeśli ciągi nie są równe |
Komparatory liczb całkowitych | Detale |
"$int1" -eq "$int2" | Prawda, jeśli liczby całkowite są równe |
"$int1" -ne "$int2" | Prawda, jeśli liczby całkowite nie są równe |
"$int1" -gt "$int2" | Prawda, jeśli int1 jest większy niż int 2 |
"$int1" -ge "$int2" | Prawda, jeśli int1 jest większe lub równe int2 |
"$int1" -lt "$int2" | Prawda, jeśli int1 jest mniejsze niż int 2 |
"$int1" -le "$int2" | Prawda, jeśli int1 jest mniejsze lub równe int2 |
Uwagi
Istnieje wiele parametrów komparatora dostępnych w bash. Nie wszystkie są jeszcze tutaj wymienione.
Jeśli oświadczenie
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
Zamykanie fi
jest konieczne, ale można pominąć klauzule elif
i / lub else
.
Średniki przed then
są standardowe składni do łączenia dwóch poleceń w jednej linii; można je pominąć tylko then
gdy then
zostanie przeniesiony do następnego wiersza.
Ważne jest, aby zrozumieć, że nawiasy [[
nie są częścią składni, ale są traktowane jako polecenie; testowany jest kod wyjścia z tego polecenia. Dlatego zawsze musisz zawrzeć spacje w nawiasach kwadratowych.
Oznacza to również, że można przetestować wynik dowolnego polecenia. Jeśli kod zakończenia polecenia jest równy zero, instrukcję uważa się za prawdę.
if grep "foo" bar.txt; then
echo "foo was found"
else
echo "foo was not found"
fi
Wyrażenia matematyczne, umieszczone w podwójnych nawiasach, również zwracają 0 lub 1 w ten sam sposób i mogą być również testowane:
if (( $1 + 5 > 91 )); then
echo "$1 is greater than 86"
fi
Można też natknąć się if
sprawozdania z pojedynczych nawiasach. Są one zdefiniowane w standardzie POSIX i gwarantujemy, że będą działać we wszystkich powłokach zgodnych z POSIX, w tym Bash. Składnia jest bardzo podobna do tej w 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
Podczas gdy pętla
#! /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
Obserwuj, czy wokół nawiasów kwadratowych są odstępy podczas testu (po instrukcji while). Te miejsca są konieczne.
Ta pętla generuje:
i is currently 0
i is currently 1
i is currently 2
i is currently 3
i is currently 4
Dla pętli
#! /bin/bash
for i in 1 "test" 3; do #Each space separated statement is assigned to i
echo $i
done
Inne polecenia mogą generować instrukcje, które można zapętlić. Zobacz przykład „Używanie pętli do iteracji po liczbach”.
To daje:
1
test
3
Używanie pętli do wyświetlania iteracji po liczbach
#! /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
To powoduje, że:
1
2
3
4
5
6
7
8
8
10
Dla pętli ze składnią w stylu C.
Podstawowy format stylu C for
pętli to:
for (( variable assignment; condition; iteration process ))
Uwagi:
- Przypisanie zmiennej
for
pętlifor
stylu C może zawierać spacje w przeciwieństwie do zwykłego przypisania - Zmienne wewnątrz pętli
for
stylu Cfor
pętli nie są poprzedzone$
.
Przykład:
for (( i = 0; i < 10; i++ ))
do
echo "The iteration number is $i"
done
Możemy również przetwarzać wiele zmiennych wewnątrz pętli for
stylu C:
for (( i = 0, j = 0; i < 10; i++, j = i * i ))
do
echo "The square of $i is equal to $j"
done
Aż do pętli
Do momentu wykonania pętli, dopóki warunek nie będzie spełniony
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
Wynik:
i=5
i=6
i=7
i=8
i=9
Kiedy i
osiągnie 10 warunek w pętli, aż staje się prawdą, a końce pętli.
kontynuować i przerwać
Przykład kontynuowania
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
Przykład przerwy
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
Pętla nad tablicą
for
pętli:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
done
Lub
for ((i=0;i<${#arr[@]};i++));do
echo "${arr[$i]}"
done
while
pętli:
i=0
while [ $i -lt ${#arr[@]} ];do
echo "${arr[$i]}"
i=$(expr $i + 1)
done
Lub
i=0
while (( $i < ${#arr[@]} ));do
echo "${arr[$i]}"
((i++))
done
Przerwanie pętli
Przerwij wiele pętli:
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
Wynik:
a
a
Przerwij pojedynczą pętlę:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break
done
done
Wynik:
a
a
b
a
c
a
d
a
e
a
f
a
Zamień instrukcję na wielkość liter
Za pomocą instrukcji case
możesz dopasować wartości do jednej zmiennej.
Argument przekazywany do case
jest rozszerzany i spróbuj dopasować do każdego wzorca.
Jeśli znaleziono dopasowanie, polecenia upto ;;
są wykonywane.
case "$BASH_VERSION" in
[34]*)
echo {1..4}
;;
*)
seq -s" " 1 4
esac
Wzorzec nie jest wyrażeniem regularnym, ale dopasowaniem wzorca powłoki (inaczej globs).
Dla pętli bez parametru listy słów
for arg; do
echo arg=$arg
done
Pętla for
bez parametru listy słów będzie iterować zamiast parametrów pozycyjnych. Innymi słowy, powyższy przykład jest równoważny z tym kodem:
for arg in "$@"; do
echo arg=$arg
done
Innymi słowy, jeśli przyłapiesz się na pisaniu for i in "$@"; do ...; done
, tylko kropla in
części, i po prostu napisać for i; do ...; done
.
Warunkowe wykonanie list poleceń
Jak korzystać z warunkowego wykonywania list poleceń
Wszelkie wbudowane polecenia, wyrażenia lub funkcje, a także dowolne zewnętrzne polecenia lub skrypty można warunkowo wykonać za pomocą &&
(i) oraz ||
(lub) operatorzy.
Na przykład spowoduje to wydrukowanie bieżącego katalogu tylko wtedy, gdy polecenie cd
zakończyło się powodzeniem.
cd my_directory && pwd
Podobnie zakończy się, jeśli polecenie cd
nie powiedzie się, zapobiegając katastrofie:
cd my_directory || exit
rm -rf *
Podczas łączenia wielu instrukcji w ten sposób należy pamiętać, że (w przeciwieństwie do wielu języków w stylu C) operatory te nie mają pierwszeństwa i są lewostronne .
Dlatego to oświadczenie będzie działać zgodnie z oczekiwaniami ...
cd my_directory && pwd || echo "No such directory"
- Jeśli
cd
powiedzie, program&& pwd
wykonuje się i drukowana jest nazwa bieżącego katalogu roboczego. O ilepwd
nie zawiedzie (rzadkość)|| echo ...
nie zostanie wykonane. - Jeśli
cd
nie powiedzie się,&& pwd
zostanie pominięty, a|| echo ...
uruchomi się.
Ale to nie będzie (jeśli myślisz, if...then...else
) ...
cd my_directory && ls || echo "No such directory"
- Jeśli
cd
nie powiedzie się,&& ls
jest pomijany, a|| echo ...
jest wykonywane. - Jeśli
cd
powiedzie, wykonywany jest program&& ls
.- Jeśli
ls
powiedzie,|| echo ...
jest ignorowane. (jak na razie dobrze) - ALE ... jeśli
ls
zawiedzie,|| echo ...
zostanie również wykonane.To
ls
, a niecd
, to poprzednie polecenie .
- Jeśli
Dlaczego warto korzystać z warunkowego wykonywania list poleceń
Wykonanie warunkowe jest szybsze niż if...then
ale jego główną zaletą jest umożliwienie wcześniejszego wyjścia funkcji i skryptów lub „zwarcia”.
W przeciwieństwie do wielu języków, takich jak C
których pamięć jest jawnie przydzielana do struktur i zmiennych i takie (i dlatego należy je zwolnić), bash
obsługuje to pod przykryciem. W większości przypadków nie musimy niczego sprzątać przed opuszczeniem funkcji. Instrukcja return
cofnie przydział wszystkiego lokalnego dla funkcji i wykonanie pobrania pod adresem zwrotnym na stosie.
Jak najszybsze wracanie z funkcji lub zamykanie skryptów może znacznie poprawić wydajność i zmniejszyć obciążenie systemu, unikając niepotrzebnego wykonywania kodu. Na przykład...
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
}