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
forpętliforstylu C może zawierać spacje w przeciwieństwie do zwykłego przypisania - Zmienne wewnątrz pętli
forstylu Cforpę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
cdpowiedzie, program&& pwdwykonuje się i drukowana jest nazwa bieżącego katalogu roboczego. O ilepwdnie zawiedzie (rzadkość)|| echo ...nie zostanie wykonane. - Jeśli
cdnie powiedzie się,&& pwdzostanie 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
cdnie powiedzie się,&& lsjest pomijany, a|| echo ...jest wykonywane. - Jeśli
cdpowiedzie, wykonywany jest program&& ls.- Jeśli
lspowiedzie,|| echo ...jest ignorowane. (jak na razie dobrze) - ALE ... jeśli
lszawiedzie,|| 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
}