BASH: opis pętli for, while, until i przykłady użycia. Podstawy programowania powłoki Ustawianie zmiennej powłoki przez wyjście z polecenia

dla VAR w 1 2 3...N robić zrobione lub w jednym wierszu: dla VAR w 1 2 3...N; robić ; zrobione
Dozwolone jest podstawianie do zmiennej zarówno wartości liczbowych, jak i znaków ASCII.
Przykład: $ for i in 1 2 A B Abc ; wykonaj echo $i; gotowe 1 2 A B Abc Przykład listy w zmienna plików przez „maskę” do transkodowania wideo: dla i w*.avi; robić ; zrobione

2. Podstawianie wyników wykonania innego polecenia

dla VAR w $(); robić ; zrobione
Przykład wykorzystania wyników polecenia seq: dla i w$(kolejny[KLUCZ]); robić echo $i; zrobione$ for i w $(seq 3); wykonaj echo $i; gotowe 1 2 3 $ dla i w $(seq 3 5); wykonaj echo $i; gotowe 3 4 5 $ dla i w $(seq 2 2 6); wykonaj echo $i; done 2 4 6 Przykład użycia wyników polecenia ls: $ for i in $(ls /$HOME/Video); wykonaj echo $i; gotowe 001.avi 002.avi 003.avi

3. Podstawienie za pomocą stylu C

dla((WYR1; WYR2; WYR3)) robić <список команд> zrobione dla((i=1; i<=3 ; i++)); robić echo $i; zrobione$ za ((i=1; i<=3 ; i++)); do echo $i; done 1 2 3 Подробнее о применении C-style в Bash

4. Wyliczanie nawiasami klamrowymi (..)

Składnia (START..END) jest obsługiwana od wersji bash 3.0+ , a od wersji bash 4.0+ obsługiwana jest składnia (START..END..INCREMENT):

dla VAR w {..} robić zrobione lub dla VAR w {....} robić zrobione Przykłady: $ for i in (1..3); wykonaj echo $i; gotowe 1 2 3 lub $ dla i w (4..8..2); wykonaj echo $i; done 4 6 8 Liczenie jest możliwe zarówno dla inkrementacji jak i dekrementacji wartości: $ for i in (6..-4..3); wykonaj echo $i; gotowe 6 3 0 -3

5. Podstawianie parametrów ( w "[e-mail chroniony]")

Wykonuje polecenia dla każdego parametru, który został przekazany do skryptu. dla VAR w [e-mail chroniony] robić zrobione lub w jednym wierszu: dla VAR w [e-mail chroniony]; robić ; zrobione
Więc jeśli utworzysz skrypt test.sh #!/kosz/sz dla VAR w [e-mail chroniony] robić Echo$var zrobione następnie uruchamiając go z parametrami: $ ./test.sh param1 param2 param3 param1 param2 param3 Część w [e-mail chroniony] można obniżyć. Następnie skrypt test.sh zostanie przepisany: #!/kosz/sz dla VAR robić Echo$var zrobione
Oto kilka przykładów (z w i bez): $ funkcja FUNC_1 ( dla VAR in [e-mail chroniony]; wykonaj echo $VAR; zrobione; ) $ FUNC_1 param1 param2 param3 param1 param2 param3 $ funkcja FUNC_2 ( dla VAR; wykonaj echo $VAR; gotowe; ) $ FUNC_2 param1 param2 param3 param1 param2 param3

6. Zastosuj kontynuuj i przerwij pętlę for

We wszystkich powyższych konstrukcjach możliwe jest użycie komendy "continue" do przejścia do następnego elementu pętli lub "break", aby wyjść z pętli.

Przykład (zakończ, gdy i=6 i nie wykonuj, gdy i=3 i i=5): dla ja w (1..8); robić jeśli[ $i -równ. 6 ]; następnie złamać; fi jeśli[ $i -równ 3 ] || [ $i -równ 5]; następnie kontyntynuj; fi echo $i zrobione Wynik wykonania: $ $ for i in (1..8); wykonaj \ > if [ $i -eq 6 ]; następnie złamać; fi; \ > if [ $i -eq 3 ] || [ $i -równ 5]; następnie kontynuuj; fi; \ > echo $i; \> gotowe 1 2 4

Degtyarev E.K. Shell - interpreter poleceń wydawanych z terminala lub z pliku wsadowego. Jest to normalny program (tzn. nie jest zawarty w jądrze systemu operacyjnego UNIX). Można go wymienić na inny lub mieć kilka. Dwie najbardziej znane wersje to: - Shell (wersja 7 UNIX) lub Bourne Shell (od nazwiska autora S.R. Bourne z Bell Labs); - C-Shell (wersje Berkley UNIX). Są podobne, ale istnieją różnice: C-Shell jest bardziej wydajny w trybie dialogowym, podczas gdy zwykły Shell ma bardziej eleganckie struktury kontrolne. Shell jest językiem programowania, ponieważ zawiera: - zmienne; - struktury kontrolne (jak jeśli); - podprogramy (w tym pliki wsadowe); - transfer parametrów; - obsługa przerwań.

7.2. Plik startowy sesji (login - plik)

Niezależnie od wersji Shell podczas wchodzenia system UNIX szuka pliku startowego sesji o predefiniowanej nazwie, aby wykonać go jako plik wsadowy; - dla wersji UNIX 7 jest to: .profile; - dla C-Shell to: .login i/lub .cshrc. W tym pliku zwykle umieszczane są polecenia: - ustawianie charakterystyki terminala; - powiadomienia typu kto, data; - instalacja katalogów wyszukiwania poleceń (zwykle: /bin, /usr/bin); - zmiana podpowiedzi z $ na inny symbol itp.

7.3. Procedura języka powłoki

To jest plik wsadowy. Istnieją dwa sposoby wywołania go w celu wykonania: 1. $ sh dothat (gdzie dothat jest jakimś plikiem wsadowym); 2. $ chmod 755 dothat (uczyń go wykonywalnym, tj. -rwxr-xr-x) $ dothat. Powinieneś znać kolejność przeszukiwania katalogów poleceń (domyślnie): - bieżący; - system / kosz; - systemowy /usr/bin. Dlatego jeśli nazwa twojego pliku wsadowego powiela nazwę polecenia w katalogach systemowych, ta ostatnia stanie się niedostępna (chyba że wpiszesz jego pełną nazwę).

7.4. Zmienne powłoki

W Shell w wersji 7 definicja zmiennej zawiera nazwę i wartość: var = wartość. Dostęp zmienny - według nazwy ze znakiem $ na początku: owoc = jabłko (definicja); echo $owoc (dostęp); jabłko (wynik echa). Więc zmienna jest łańcuchem. Możliwe jest łączenie łańcuchów: $ owoc = jabłko $ owoc = sosna$owoc $ echo $owoc ananas $ owoc = jabłko $ wino = $(owoc)jack $ echo $wino applejack $ Inne sposoby ustawienia wartości zmiennej to dane wejściowe z pliku lub wyjście z polecenia (p.punkt 7.6), a także przypisanie wartości do zmiennej - parametr pętli for z listy wartości określonej wprost lub domyślnie (p.punkt 7.9). Zmienną może być: 1) Część pełnej nazwy pliku: $d/filename, gdzie $d jest zmienną (na przykład d = /usr/bin). 2) Część polecenia: $ S = "sortuj + 2n + 1 - 2" (spacje wymagają cudzysłowów "") $ $S tenis/lpr $ $S koszykówka/lpr $ $S pingpong/lpr $ Jednak wewnątrz wartości bo polecenia nie mogą być symbolami |, >,

7.5. Predefiniowane zmienne powłoki

Niektóre z nich można tylko przeczytać. Najczęściej: HOME - katalog "domowy" użytkownika; służy jako domyślny argument cd; PATH to zestaw katalogów, w których UNIX szuka poleceń; PS1 - podstawowa podpowiedź (ciąg) systemu (dla v.7 - $). Zmiana PS1 (podpowiedź) odbywa się zwykle w pliku logowania, na przykład: PS1 = ? lub PS1 = „?” (ze spacją, co jest wygodniejsze). Zmień PATH: $ echo $PATH - zobacz; :/bin:/usr/bin - wartość PATH; $ cd - "dom"; $ mkdir bin - nowy katalog; $ echo $HOME - patrz; /users/mariann - bieżący katalog; $ PATH = :$HOME/bin:$PATH - zmień PATH; $ echo $PATH - patrz; :/users/maryann/bin:/bin:/usr/bin - nowa wartość PATH.

7.6. Ustawianie zmiennej powłoki z danymi wyjściowymi z polecenia

Przykład 1: $ now = `data` (gdzie `` to poprzednie cudzysłowy) $ echo $now niedziela 14 lutego 12:00:01 PST 1985 $ Przykład 2: (pobieranie wartości zmiennej z pliku): $ menu = `karma dla kotów` $ echo $menu jabłka cheddar chardonnay (powroty karetki są zastępowane spacjami).

7.7. Zmienne powłoki — argumenty procedury

Jest to specjalny typ zmiennej zwany liczbami. Przykład: $ dothis winogrona jabłka gruszki (procedura). Następnie parametry pozycyjne (argumenty) tego polecenia są dostępne według nazwy: $1 = `winogrona` $2 = `jabłka` $3 = `gruszki` i tak dalej. do 9 USD. Istnieje jednak polecenie shift, które przesuwa nazwy do pozostałych argumentów, jeśli jest ich więcej niż 9 (okno ma 9 szerokości). Inny sposób na uzyskanie wszystkich argumentów (nawet jeśli jest ich więcej niż 9): $*, co jest równoważne $1$2 ... Liczba argumentów jest przypisana do innej zmiennej: $#(sharp). Wreszcie nazwa procedury to $0; zmienna $0 nie jest brana pod uwagę przy obliczaniu $#.

7.8. Oświadczenia dotyczące powłoki strukturalnej

Oprócz procedur Shell ma instrukcje strukturalne, takie jak „if-else” i „while-do”. Programowanie powłoki, oprócz pisania procedur, służy do: - opracowywania algorytmów przed kodowaniem w językach C lub FORTRAN-77 (brak kompilacji, linkowania, ładowania, łatwość debugowania); - nauczanie zasad programowania nie-programistów.

7.9. instrukcja pętli for

Zróbmy plik wsadowy makelist (procedura) $ cat makelist sort +1 -2 osoby | tr -d -9 | pr -h Rozkład | lpr. Jeśli istnieje kilka plików zamiast jednej osoby, na przykład: adminpeople, hardpeople, softpeople,... to należy powtórzyć procedurę z różnymi plikami. Jest to możliwe za pomocą operatora for -. Składnia: for in do done Słowa kluczowe dla, do, done są pisane od początku wiersza. Przykład (zmiana procedury makelisty) do pliku w adminpeople, hardpeople, softpeople Sortuj +1 -2 $plik | tr ... | lpr zrobione. Możesz użyć metaznaków powłoki na liście wartości. Przykład: dla pliku w *osobach (dla wszystkich nazw kończących się na osobach) zrób ... gotowe. Jeżeli pominięto in, to domyślną listą wartości jest lista argumentów procedury, która zawiera pętlę, a jeżeli pętli nie ma w procedurze, to lista parametrów wiersza poleceń (czyli komenda działa jako procedura). Przykład: for file do ... done Aby zadzwonić do makelist adminpeople hardpeople softpeople, zrobiono by to samo.

7.10. Oświadczenie warunkowe, jeżeli

Używamy nazw zmiennych reprezentujących wartości parametrów procedury: sort +1 -2 $1 | tr ... | lpr Przykład nieprawidłowego wywołania: makelist (bez parametrów), gdzie $1 jest niezdefiniowane. Możesz naprawić błąd, sprawdzając liczbę argumentów - wartość zmiennej $# za pomocą instrukcji if -. Przykład: (zmodyfikowana lista makelist): if test $# -eq 0 then echo "Musisz podać nazwę pliku" exit 1 w przeciwnym razie sortuj +1 -2 $1 | tr ... | lpr fi Tutaj test i exit to test (patrz Rozdział 7.11) i polecenia wyjścia. Zatem składnia instrukcji if to: if ; następnie; Słowa kluczowe if, then, else i fi są pisane od początku wiersza. Pomyślne wykonanie procedury oznacza, że ​​zwraca wartość true = 0 (zero) (niepowodzenie - zwracana wartość nie jest równa 0). Instrukcja exit 1 ustawia wartość zwracaną na 1 w przypadku niepowodzenia wykonania makelisty i kończy procedurę. Zagnieżdżone if są możliwe. Dla else if istnieje skrót elif, który jednocześnie oznacza fi.

7.11. polecenie „test”

Nie jest częścią Shell, ale jest używany w procedurach Shell. Istnieją trzy rodzaje kontroli: - ocena wartości liczbowych; - ocena typu pliku; - ocena rzędów. Każdy typ ma swoje własne prymitywy (operacje op). W przypadku liczb składnia jest następująca: N op M, gdzie N, M to liczby lub zmienne liczbowe; op przyjmuje wartości: -eq, -ne, gt, -lt, -ge, -le (w zwykłym znaczeniu, jak na przykład w FORTRAN). Składnia pliku to: op nazwa_pliku, gdzie op przyjmuje wartości: -s (plik istnieje i nie jest pusty); -f (plik, nie katalog); -d (katalog plików (katalog) -w (plik do zapisu) -r (plik do odczytu) Dla łańcuchów składnia jest następująca: S op R, gdzie S, R to łańcuchy lub zmienne łańcuchowe, lub op1 S op przyjmuje wartości := (równoważność) != (nie równoważność) op1 przyjmuje wartości: -z (łańcuch o zerowej długości) -n (łańcuch o niezerowej długości) Na koniec kilka sprawdzeń różnych typów można połączyć z operacjami logicznymi -a ( AND) i -o (LUB) Przykłady: $ if test -w $2 -a -r S1 > then cat $1 >> $2 > else echo "nie można dołączyć" > fi $ nawiasy kwadratowe, tj. if [...] zamiast jeśli test ... .

7.12. instrukcja pętli while

Składnia: while do done Jeśli "polecenie" się powiedzie, wykonaj "polecenia" zakończone słowem kluczowym done. Przykład: if test $# -eq 0 then echo "Użycie: $0 plik ..." > &2 wyjdź z fi podczas testu $# -gt 0 wykonaj jeśli test -s $1 then echo "brak pliku $1" > &2 w przeciwnym razie sortuj + 1 - 2$ | tr -d ... (procedury) fi shift (* renumeracja argumentów *) done Procedury są wykonywane na wszystkich argumentach.

7.13. dopóki instrukcja pętli

Odwraca warunek powtarzania od while Składnia: dopóki wykonaj Dopóki "polecenie" się nie powiedzie, wykonuj polecenia zakończone słowem gotowe. Przykład: if test S# -eq 0 then echo "Użyj $0 plik..." > &2 wyjdź fi do testu S# -eq 0 wykonaj jeśli test -s $1 then echo "brak pliku $1" > &2 w przeciwnym razie sortuj +1 - 2$ | tr -d ... (procedura) fi shift (przesunięcie argumentu) done Podobne do poprzedniego.

7.14. oświadczenie o wyborze przypadku

Składnia: wielkość liter w ciągu1) ;; ciąg2);; ciąg3) ... itd. ... esac Przykład: Niech procedura ma opcję -t, którą można podać jako pierwszy parametr: ............... razem = bez przypadku $1 w -t) razem = tak przesunięcie ;; -?) echo "$0: brak opcji $1" exit ;; esac jeśli test $razem = tak to sortuj ... fi gdzie? - metaznak (jeśli -?, czyli "inna" opcja inna niż -t, to błąd). Można używać wszystkich metaznaków powłoki, w tym ?, *, [-]. Łatwo jest dodać (w przykładzie) inne opcje, po prostu rozszerzając obudowę.

7.15. Korzystanie z plików tymczasowych w katalogu /tmp

Jest to specjalny katalog, w którym wszyscy użytkownicy mogą zapisywać wszystkie pliki. Jeśli jakaś procedura tworząca plik tymczasowy jest używana przez kilku użytkowników, konieczne jest zapewnienie niepowtarzalności nazw. utworzone pliki. Standardową sztuczką jest nazwa pliku tymczasowego $0$$, gdzie $0 to nazwa procedury, a $$ to standardowa zmienna równa unikalnemu numerowi identyfikacyjnemu procesu wykonującego bieżące polecenie. Chociaż administrator okresowo usuwa pliki tymczasowe w /tmp, dobrą praktyką jest jawne usuwanie ich po użyciu.

7.16. Komentarze w procedurach

Zaczynają się od dwukropka:, który jest uważany za polecenie puste, a tekst komentarza jest jego argumentem. Aby zapobiec interpretacji przez Shell metaznaków ($, * itp.), zaleca się ująć tekst komentarza w pojedyncze cudzysłowy. W niektórych wariantach systemu operacyjnego UNIX uwaga zaczyna się od znaku #.

7.17. Przykład procedury

:"Ta procedura działa na plikach zawierających nazwy" : "i numery telefonów", :"sortuje je razem lub osobno i wyświetla wynik na" :"ekranu lub drukarce" :"Klawisze procedury:" :"-t (razem) - scalaj i sortuj wszystkie pliki razem" :"-p (drukarka) - drukuj pliki na drukarce" if test $# - eq 0 then echo "Użycie: $ 0 plik ... " > & 2 exit fi together = no print = no podczas gdy test $# -gt 0 wykonaj przypadek $1 w -t) razem = tak przesunięcie ;; -p) print = tak przesunięcie ;; -?) echo "$0: brak opcji $1" exit ;; *) jeśli test $razem = tak to sortuj -u +1 -2 $1 | tr ... > /tmp/$0$$ if $print = no to cat /tmp/$0$$ else lpr -c /tmp/$0$$ fi rm /tmp/$0$$ wyjdź w przeciwnym razie if test -s $1 to echo "brak pliku $1" > &2 jeszcze sortuj +1 -2 $1 | tr...> /tmp/$0$$ if $print = no then cat /tmp/$0$$ else lpr -c /tmp/$0$$ fi rm /tmp/$0$$ fi shift fi;; esac zrobione. Procedura sprawdza liczbę parametrów $# i jeśli wynosi zero, kończy. W przeciwnym razie przetwarza parametry (instrukcja case). Parametrem może być klucz (znak poprzedzony znakiem minus) lub nazwa pliku (ciąg reprezentowany przez metaznak *). Jeśli klucz jest niepoprawny (metaznak? jest inny niż t i p), procedura kończy się. W przeciwnym razie, w zależności od obecności klawiszy t i p, wykonywane są akcje zadeklarowane w komentarzu na początku procedury.

7.18. Obsługa przerwań w procedurach

Jeżeli podczas wykonywania procedury zostanie odebrany sygnał przerwania (na przykład z klawisza BREAK lub DEL), to wszystkie utworzone pliki tymczasowe pozostaną nieusunięte (do czasu, gdy zrobi to administrator) ze względu na natychmiastowe zakończenie procesu. Najlepszym rozwiązaniem jest obsługa przerwań w ramach procedury za pomocą operatora pułapki: Składnia: trap "argumenty poleceń" sygnały... Cudzysłów stanowi pierwszy argument kilku poleceń oddzielonych średnikami. Zostaną wykonane, jeśli wystąpi przerwanie określone argumentami sygnałów (liczba całkowita): 2 - gdy przerwasz proces; 1 - jeśli jesteś "zawieszony" (odłączony od systemu) itp. Przykład (rozwój poprzedniego): przypadek $1 w ..... *) trap "rm /tmp/*; exit" 2 1 (usuwanie pliki tymczasowe) if test -s $1 .............. rm /tmp/* Byłoby lepiej: trap "rm /tmp/* > /dev/null; exit" 2 1 as przerwanie może nastąpić przed utworzeniem pliku /tmp/$0$$, a alarm dotyczący tego przypadku jest przekierowywany do urządzenia zerowego.

7.19. Wykonywanie operacji arytmetycznych: expr

Polecenie expr ocenia wartość wyrażenia podanego jako argument i wysyła wynik na standardowe wyjście. Najciekawszą aplikacją jest wykonywanie operacji na zmienne językowe Powłoka. Przykład zsumowania 3 liczb: $ cat sum3 expr $1 + $2 + 3 $ chmod 755 sum3 $ sum3 13 49 2 64 $ Przykład bezpośredniego użycia polecenia: $ expr 13 + 49 + 2 + 64 + 1 129 $ Następujące operatory arytmetyczne można używać w expr - ry: +, -, *, /,% (reszta). Wszystkie operandy i operacje muszą być oddzielone spacjami. Zauważ, że znak mnożenia musi być ujęty w cudzysłów (pojedynczy lub podwójny), na przykład: "*", ponieważ znak * ma specjalne znaczenie w powłoce. Bardziej złożony przykład wyrażenia w procedurze (fragment): num = "wc -l

7.20. Procedury debugowania powłoki

Istnieją trzy narzędzia umożliwiające debugowanie procedur. 1) Umieszczanie poleceń echa w ciele procedury w celu wydawania komunikatów będących śladem wykonania procedury. 2) Opcja -v (verbose = verbose) w poleceniu powłoki powoduje wypisanie polecenia na ekranie przed jego wykonaniem. 3) Opcja -x (wykonaj) w poleceniu powłoki powoduje, że polecenie jest drukowane na ekranie podczas jego wykonywania, zastępując wszystkie zmienne ich wartościami; jest to najpotężniejsze narzędzie.

  • instruktaż

Podstawy BASH. Część 2.
Przepraszam za tak duże opóźnienie między artykułami, ale sesja daje o sobie znać w najbardziej nieodpowiednim momencie :)
Dziękuję wszystkim za komentarze, krytykę i uzupełnienia, które pojawiły się w komentarzach do ostatniego.
Ta część, zgodnie z obietnicą, będzie poświęcona pętlom, operacjom matematycznym i wykorzystaniu poleceń zewnętrznych.
Zaczynajmy.

cykle. pętla for-in.

Operator for-in jest przeznaczony do uzyskiwania dostępu do wartości wymienionych na liście jeden po drugim. Każda wartość z kolei na liście jest przypisana do zmiennej.
Składnia jest następująca:
dla zmiennej na liście_wartości
robić
zespoły
zrobione

Rozważ mały przykład:

#!/kosz/bash
dla i w 0 1 2 3 4 #zmiennej $i zostaną przypisane wartości od 0 do 4 włącznie
robić
echo "Numer konsoli to $i" >> /dev/pts/$i #Zapisz ciąg "Numer konsoli to $i" do pliku /dev/pts/$i
zrobione #cykl zakończony
wyjście 0

Po wykonaniu przykładu na pierwszych 5 wirtualnych konsolach (terminalach) pojawi się linia z jej numerem. Wartości z listy są naprzemiennie podstawiane do zmiennej $i i praca z wartością tej zmiennej odbywa się w pętli

cykle. podczas pętli.

Pętla while jest bardziej złożona niż pętla for-in i służy do powtarzania poleceń, gdy niektóre wyrażenia są prawdziwe (kod powrotu = 0).
Składnia operatora jest następująca:
while wyrażenie lub polecenie, które zwraca kod powrotu
robić
zespoły
zrobione

Przykład działania pętli pokazano w poniższym przykładzie:

#!/kosz/bash
again=tak #przypisz ponownie wartość "tak" do zmiennej
while [ "$again" = "yes" ] #Będziemy zapętlać, aż $again będzie równe "tak"
robić
echo "Proszę podać nazwę:"
przeczytaj imię
echo "Wpisana nazwa to $name"

Echo "Czy chcesz kontynuować?"
Przeczytaj ponownie
zrobione
echo "Do widzenia"


A teraz wynik skryptu:
[e-mail chroniony]:~$ ./bash2_primer1.sh
Podaj nazwę:
ite
Wprowadzona nazwa to ite
Czy chcesz kontynuować?
tak
Podaj nazwę:
Michał
Wpisane imię to mihail
Czy chcesz kontynuować?
nie
PA pa

Jak widać, pętla jest wykonywana, dopóki nie wpiszemy czegoś innego niż „tak”. Pomiędzy zrobić i zrobić możesz opisać dowolne struktury, instrukcje itp., wszystkie zostaną wykonane w pętli.Ale powinieneś być ostrożny z tą pętlą, jeśli uruchomisz w niej jakiekolwiek polecenie bez zmiany zmiennej wyrażenia, możesz uzyskać w nieskończoną pętlę.
Przejdźmy teraz do warunku prawdy. Po chwili, tak jak w instrukcji warunkowej if-then-else, możesz wstawić dowolne wyrażenie lub polecenie, które zwraca kod powrotu, a pętla zostanie wykonana tak długo, jak kod powrotu = 0! Operator „[” jest odpowiednikiem polecenia test, które sprawdza prawdziwość przesłanego do niego warunku.

Spójrzmy na inny przykład, wziąłem go z książki Advanced Bash Scripting. Bardzo mi się podobało :), ale trochę to uprościłem. W tym przykładzie zapoznamy się z innym rodzajem pętli UNTIL-DO.. Jest to prawie kompletny odpowiednik pętli WHILE-DO, tylko że jest wykonywany, gdy jakieś wyrażenie jest fałszywe.
Oto przykład:

#!/kosz/bash
echo "Wpisz licznik: "
przeczytaj dywidendę
echo "Wpisz mianownik: "
przeczytaj dzielnik

dnd=$dividend #zmodyfikujemy zmienne dywidendy i dzielnika,
#zachowaj ich wiedzę w innych zmiennych, ponieważ oni nam dają
#potrzebować
dvs=$dzielnik
reszta = 1

Do [ "$reszta" -eq 0 ]
robić
niech „reszta = dzielnik % dywidendy”
dywidenda = $ dzielnik
dzielnik=$reszta
zrobione

Echo "gcd liczb $dnd i $dvs = $dywidenda"


Wynik wykonania skryptu:
[e-mail chroniony]:~$ ./bash2_primer3.sh
Wpisz licznik:
100
Wprowadź mianownik:
90
NWD liczb 100 i 90 = 10

Operacje matematyczne

niech komenda.
Polecenie let wykonuje operacje arytmetyczne na liczbach i zmiennych.
Rozważmy mały przykład, w którym wykonujemy obliczenia na wprowadzonych liczbach:
#!/kosz/bash
echo "Wpisz: "
czytać
echo "Wpisz b: "
przeczytaj b

Niech "c = a + b" #dodanie
echo "a+b= $c"
niech "c = a / b" #dziel
echo "a/b= $c"
niech „c<<= 2" #сдвигает c на 2 разряда влево
echo "c po przesunięciu o 2 bity: $c"
niech "c = a % b" # znajduje resztę z dzielenia a przez b
echo "$a / $b. reszta: $c "


Wynik wykonania:
[e-mail chroniony]:~$ ./bash2_primer2.sh
Wprowadź a:
123
Wpisz b:
12
a+b=135
a/b=10
c po przesunięciu o 2 bity: 40
123 / 12. reszta: 3

Cóż, jak widać, nic skomplikowanego, lista operacji matematycznych jest standardowa:
+ - dodawanie
- - odejmowanie
* - mnożenie
/ - dział
** - potęgowanie
% - modulo(dzielenie modulo), reszta z dzielenia
let pozwala na używanie skrótów poleceń arytmetycznych, zmniejszając w ten sposób liczbę używanych zmiennych. Na przykład: a = a+b jest równoważne a +=b itd.

Praca z programami zewnętrznymi podczas pisania skryptów powłoki

Zacznijmy od przydatnej teorii.
Przekierowanie strumienia.
Bash (i wiele innych powłok) ma wbudowane deskryptory plików: 0 (stdin), 1 (stdout), 2 (stderr).
stdout - Wyjście standardowe. Tutaj trafia wszystko, co wyprowadza programy.
stdin - wejście standardowe. To wszystko, co użytkownik wpisuje w konsoli
stderr — standardowe wyjście błędów.
W przypadku operacji na tych uchwytach są Symbole specjalne:> (przekierowanie wyjścia),< (перенаправление ввода). Оперировать ими не сложно. Например:
przekieruj wyjście polecenia cat /dev/random do /dev/null (całkowicie bezużyteczna operacja :))) lub
zapisz zawartość bieżącego katalogu do pliku listingu (już bardziej przydatne)
Jeśli istnieje potrzeba dołączenia do pliku (w przypadku używania ">" jest on zastępowany), należy użyć ">>" zamiast ">"
po poproszeniu sudo o podanie hasła, zostanie ono pobrane z pliku my_password tak, jakbyś wprowadził je z klawiatury.
Jeśli potrzebujesz wpisać do pliku tylko błędy, które mogą wystąpić podczas działania programu, możesz użyć:
./program_z_błędem 2> plik_błędu
liczba 2 przed ">" oznacza, że ​​wszystko, co znajduje się w deskryptorze 2 (stderr), powinno zostać przekierowane.
Jeśli konieczne jest wymuszenie na stderr zapisu na stdout, można to zrobić w następujący sposób. sposób:
znak "&" oznacza wskaźnik do deskryptora 1 (stdout)
(Domyślnie stderr zapisuje do konsoli, w której pracuje użytkownik (bardziej prawdopodobne jest, że zapisze na wyświetlaczu)).
2. Przenośniki.
Potok jest bardzo potężnym narzędziem do pracy z konsolą Bash. Składnia jest prosta:
zespół1 | komenda 2 - oznacza, że ​​wyjście komendy 1 zostanie przekazane na wejście komendy 2
Potoki można grupować w łańcuchy i wyprowadzać za pomocą przekierowania do pliku, na przykład:
ls-la | grep "hash" |sort > sortilg_list
Wyjście polecenia ls -la jest przesyłane potokiem do polecenia grep, które wybiera wszystkie wiersze zawierające słowo hash, i przesyłane potokiem do polecenia sort, które zapisuje wynik w pliku lista_sortowania. Wszystko jest całkiem jasne i proste.

Najczęściej skrypty Bash są wykorzystywane jako automatyzacja niektórych rutynowych operacji w konsoli, stąd czasami konieczne staje się przetworzenie stdout jednego polecenia i przeniesienie go na stdin do innego polecenia, podczas gdy wynik wykonania jednego polecenia musi zostać przetworzony w w jakiś sposób. W tej sekcji postaram się wyjaśnić podstawowe zasady pracy z poleceniami zewnętrznymi wewnątrz skryptu. Myślę, że podałem wystarczająco dużo przykładów i teraz mogę napisać tylko główne punkty.

1. Przekazanie wyjścia do zmiennej.
Aby zapisać wyjście polecenia do zmiennej, wystarczy umieścić polecenie w cudzysłowie, na przykład
a = `echo "qwerty"`
echo $a

Wynik pracy: qwerty


Jeśli jednak chcesz zapisać listę katalogów do zmiennej, musisz odpowiednio przetworzyć wynik, aby umieścić dane w zmiennej. Rozważmy mały przykład:
LIST=`znajdź /svn/ -type d 2>/dev/null| awk "(FS="/") (wypisz $4)"| sortuj|uniq| tr "\n" " ""`
dla ONE_OF_LIST w $LIST
robić
svnadmin hotcopy /svn/$ONE_OF_LIST /svn/temp4backup/$ONE_OF_LIST
zrobione

Tutaj używamy pętli do zrobienia, aby zarchiwizować wszystkie katalogi w folderze /svn/ za pomocą polecenia svnadmin hotcopy (co nie ma znaczenia w naszym przypadku, tylko jako przykład). Najbardziej interesującą linią jest: LIST=`find /svn/ -type d 2>/dev/null| awk "(FS="/") (wypisz $4)"| sortuj|uniq| tr "\n" " "` W nim do zmiennej LIST przypisywane jest wykonanie polecenia find przetwarzanego przez polecenia awk, sort, uniq, tr (nie rozważymy wszystkich tych poleceń, ponieważ jest to osobny artykuł). Zmienna LIST będzie zawierać nazwy wszystkich katalogów w folderze /svn/ umieszczonych w jednej linii (w celu odpowietrzenia pętli.

Jak widać, wszystko nie jest trudne, wystarczy zrozumieć zasadę i napisać kilka własnych skryptów. Podsumowując, chciałbym życzyć powodzenia w nauce ogólnie BASH i Linuxa. Krytyka jak zwykle jest mile widziana. Następny artykuł będzie prawdopodobnie poświęcony korzystaniu z programów takich jak sed, awk.

Język programowania powłoki ma kilka konstrukcji, które zapewnią elastyczność Twoim programom:

  • komentarze pozwalają opisać funkcje programu;
  • "tutaj dokument" pozwala na umieszczanie w programach powłoki łańcuchów, które będą przekierowywane jako dane wejściowe do niektórych poleceń programu powłoki;
  • polecenie wyjścia pozwala zakończyć program w żądanym punkcie i użyć kodów powrotu;
  • konstrukcje pętli dla, while pozwalają na powtórzenie grupy poleceń w pętli;
  • warunkowe polecenia if i case wykonują grupę poleceń, jeśli spełniony jest jakiś warunek;
  • Polecenie break pozwala na bezwarunkowe wyjście z pętli.

9.3.1. Uwagi

Aby umieścić komentarze w programie, użyj znaku #. Jeśli po poleceniu znajduje się znak #, to samo polecenie jest wykonywane, a komentarz jest ignorowany. Format wiersza komentarza:

#komentarz

9.3.2. "tutaj dokument"

"Dokument tutaj" pozwala na umieszczenie wierszy w programie powłoki, które są przekierowywane jako dane wejściowe do polecenia w tym programie. Jest to jeden ze sposobów dostarczania danych wejściowych dla polecenia w programie powłoki bez używania oddzielnego pliku. Wpis składa się ze znaku przekierowania<< и разделителя, который указывает начало и конец строк ввода. В качестве разделителя может использоваться один символ или строка символов. Чаще всего это знак!.

Format polecenia jest następujący:

Komenda<...linie wejściowe... ogranicznik

9.3.3. Używanie ed w programie powłoki

"Tutaj dokument" sugeruje sposób użycia ed w programie powłoki. Powiedzmy, że chcesz utworzyć program powłoki, który wywoła edytor ed, dokona globalnych zmian w pliku, zapisze zmiany w pliku, a następnie zakończy pracę ed. Poniższy ekran przedstawia zawartość programu ch.text, który wykonuje te zadania:

$kot.tekst echo Wpisz nazwę pliku read file1 echo Wpisz dokładny tekst, który ma zostać zmieniony. przeczytaj stary_tekst echo Wpisz dokładnie nowy tekst, aby zastąpić powyższy. przeczytaj nowy_tekst ed - $plik1<

Zwróć uwagę na znak - (minus) w poleceniu ed. Ta opcja zapobiega drukowaniu liczby znaków na ekranie. Zwróć także uwagę na format polecenia ed dla globalnego zastąpienia:

G/$stary_tekst/s//$nowy_tekst/g

Program wykorzystuje 3 zmienne: plik1, stary_tekst, nowy_tekst. Po uruchomieniu ten program używa polecenia read, aby uzyskać wartości tych zmiennych. Te zmienne zawierają następujące informacje:
plik - nazwa pliku do edycji;
stary_tekst - tekst do zmiany;
nowy_tekst - nowy tekst.

Zmienne są wprowadzane do programu, tutaj dokument przekierowuje globalne polecenie zamiany, polecenie zapisu i polecenie uzupełniania do polecenia ed. Uruchom program ch.text. Uzyskaj następujący ekran:

$ch.tekst Wpisz notatkę o nazwie pliku Wpisz dokładny tekst, który chcesz zmienić. Drogi Johnie: Wpisz dokładnie nowy tekst, aby zastąpić powyższy. Do czego może to dotyczyć: $ notatka o kotach Do czego może to dotyczyć: $

9.3.4. Kody ukończenia

Większość poleceń powłoki zwraca kody wskazujące, czy polecenie zakończyło się pomyślnie. Jeśli zwracana wartość wynosi 0 (zero), oznacza to, że polecenie się powiodło. Kody powrotu nie są automatycznie drukowane, ale można je pobrać jako wartość specjalnego parametru powłoki $?.

9.3.4.1. Sprawdź kody wyjścia

Po interaktywnym wykonaniu polecenia możesz zobaczyć kod zakończenia podczas wpisywania:

echo $? Rozważmy następujący przykład: $ cat hi To jest plik hi. $ echo $? 0 $ kot cześć kot: nie można otworzyć cześć $ echo $? $2

W pierwszym przypadku plik hi istnieje w twoim katalogu i masz uprawnienia do odczytu. Za pomocą polecenia cat możesz wydrukować zawartość pliku. Wynikiem polecenia cat jest kod powrotu 0, który otrzymujesz z parametrem $?. W drugim przypadku plik albo nie istnieje, albo nie masz dostępu do odczytu. Polecenie cat drukuje komunikat diagnostyczny i zwraca kod 2.

program powłoki kończy działanie normalnie po wykonaniu ostatniego polecenia w pliku. Możesz jednak użyć polecenia wyjścia, aby zakończyć program. Co ważniejsze, możesz użyć polecenia exit, aby uzyskać kody zakończenia programu powłoki.

9.3.5. Cykle

Instrukcje pętli for i while umożliwiają wielokrotne wykonanie polecenia lub sekwencji poleceń.

9.3.5.1. za oświadczenie

Instrukcja for wykonuje sekwencję poleceń dla każdego elementu listy. Ma format:

Dla zmiennych na liście_wartości robić polecenie_1 polecenie_2 . . . ostatnie polecenie zrobione

Dla każdej iteracji pętli kolejny element listy przypisywany jest zmiennej podanej w instrukcji for. Do tej zmiennej można się odwoływać w dowolnym miejscu poleceń w instrukcji do. Konstruując każdą sekcję poleceń, musisz upewnić się, że każda z nich pasuje do gotowego na końcu pętli.

Zmienna może mieć dowolną nazwę. Na przykład, jeśli twoja zmienna ma nazwę zmienna, odwołanie do zmiennej $zmienna na liście poleceń spowoduje, że wartość będzie dostępna. Jeśli operator in zostanie pominięty, wartość var ​​będzie zbiorem argumentów określonych w poleceniu i dostępnych w parametrze specjalnym $*. Dla każdej wartości zostanie wykonana lista poleceń między słowem kluczowym do i done.

Gdy polecenia są wykonywane dla ostatniego elementu listy, program wykona poniższą linię done.

9.3.5.2. podczas gdy oświadczenie

Instrukcja while loop używa 2 grup poleceń. Wykona sekwencję poleceń z drugiej grupy (lista do ... done), aż ostatnie polecenie z pierwszej grupy (lista while) zwróci wartość true, wskazując, że wyrażenie po do może zostać wykonane.

Ogólny format instrukcji while loop to:

Chwila polecenie_1 . . . ostatnie polecenie robić polecenie_1 . . . ostatnie polecenie zrobione

Na przykład program enter.name używa pętli while do wprowadzenia listy nazw do pliku. Program składa się z następujących linii poleceń:

$ cat enter.name podczas odczytu x wykonaj echo $x>>xfile gotowe $

Z kilkoma dodatkami otrzymujemy następujący program:

$ cat enter.name echo Proszę wpisać imię każdej osoby, a następnie a echo Proszę zakończyć listę nazwisk znakiem<^d>while read x wykonaj echo $x>>xfile done echo xfile zawiera następujące nazwy: cat xfile $

Należy pamiętać, że po zakończeniu pętli program wykonuje poniższe polecenia.

Pierwsze dwa polecenia echa używają znaków specjalnych, więc musisz użyć cudzysłowów, aby uniknąć specjalnego znaczenia. Poniższy ekran przedstawia dane wyjściowe programu enter.name:

$enter.name Proszę wpisać imię i nazwisko każdej osoby, a następnie a Proszę zakończyć listę nazwisk na<^d>Mary Lou Janice <^d>xfile zawiera następujące imiona: Mary Lou Janice $

Po zakończeniu pętli program wypisze wszystkie nazwy zawarte w pliku x.

9.3.6. Korzystanie z /dev/null

System plików ma plik /dev/null, w którym możesz przechowywać niechciane dane wyjściowe. Na przykład, jeśli po prostu wpiszesz komendę who, system odpowie, kto pracuje w systemie. Jeśli przekierujesz dane wyjściowe tego polecenia do /dev/null:

Kto > /dev/null nie otrzyma odpowiedzi.

9.3.7. Instrukcje warunkowe

jeśli ... to oświadczenie

Polecenie if mówi programowi powłoki, aby wykonał sekwencję poleceń po tym, jeśli ostatnie polecenie na liście poleceń w konstrukcji if powiodło się. Konstrukcje if kończą się słowem kluczowym fi.

Ogólny format konstrukcji if to:

Jeśli polecenie_1 . . . ostatnie polecenie następnie polecenie_1 . . . ostatnie polecenie fi

Na przykład program powłoki wyszukiwania demonstruje użycie konstrukcji if ... then. Program wyszukujący używa polecenia grep do wyszukiwania słowa w pliku. Jeśli grep się powiedzie, program wyświetli znalezione słowo. Ekran będzie wyglądał tak:

$ szukaj kota echo Wpisz słowo i nazwę pliku. przeczytaj plik tekstowy jeśli grep $słowo $plik to echo $słowo jest w $pliku fi $

Ten program wyświetla dane wyjściowe polecenia grep. Jeśli chcesz przechowywać odpowiedź systemu na polecenie grep w swoim programie, użyj pliku /dev/null, zmieniając wiersz polecenia if na następujący:

grep $słowo $plik > /dev/null

Teraz uruchom polecenie wyszukiwania. Odpowie tylko komunikatem określonym po poleceniu echo.

Konstrukcja if ... then ... else może wykonać alternatywny zestaw poleceń po else, jeśli sekwencja if jest fałszem. Format tej konstrukcji jest następujący:

Jeśli polecenie_1 . . . ostatnie polecenie .linthen polecenie_1 . . . ostatnie polecenie w przeciwnym razie polecenie_1 . . . ostatnie polecenie fi

Dzięki tej konstrukcji możesz ulepszyć program wyszukiwania tak, aby podawał zarówno znalezione słowo, jak i informację, że słowo nie zostało znalezione. W takim przypadku program wyszukiwania wyglądałby tak:

$ szukaj kota echo Wpisz słowo i nazwę pliku. przeczytaj plik słów, jeśli grep $słowo $plik > /dev/null then echo $słowo jest w $pliku else echo $słowo NIE znajduje się w $pliku fi $

polecenie testowe

Polecenie test służy do organizowania pętli. Sprawdza, czy pewne warunki są prawdziwe i jest przydatne do organizowania konstrukcji warunkowych. Jeśli warunek jest spełniony, pętla będzie kontynuowana. Jeśli warunek jest fałszywy, pętla się zakończy i zostanie wykonane następne polecenie. Kilka przykładów użycia polecenia test: test -r plik prawda, jeśli plik istnieje i można go odczytać; test -w plik prawda, jeśli plik istnieje i jest zapisywalny; test -x plik prawda, jeśli plik istnieje i jest wykonywalny; test -s plik prawda, jeśli plik istnieje i ma co najmniej jeden znak; test var1 -eq var2 prawda, jeśli zm1 jest równa zm2; test zm1 -ne zm2 prawda, jeśli zmienna1 nie jest równa zm2.

Przykład. Stwórzmy program powłoki, który przeniesie wszystkie pliki wykonywalne z bieżącego katalogu do katalogu bin. Aby to zrobić, użyj polecenia test -x, aby wybrać pliki wykonywalne. Program mv.file będzie wyglądał tak:

$cat mv.plik echo wpisz w katalogu ścieżka odczyt ścieżki do pliku wykonaj if test -x $plik then mv $plik $ścieżka/$plik fi gotowe $

Konstrukcja case ... esac pozwala wybrać jeden z kilku wzorców, a następnie wykonać listę poleceń dla tego wzorca. Wyrażenie szablonu musi zaczynać się słowem kluczowym in, a prawy nawias musi być umieszczony po ostatnim znaku każdego szablonu. Sekwencja poleceń dla każdego wzorca kończy się dwoma znakami;;. Instrukcja case musi kończyć się słowem kluczowym esac.

Ogólny format konstrukcji przypadku to:

słowo literowe w wzór1) wiersz poleceń 1 . . . ostatnia linia poleceń ;;wzór2) wiersz poleceń 1 . . ostatnia linia poleceń ;;wzór3) wiersz poleceń 1 . . ostatnia linia poleceń ;; *)wiersz poleceń 1 . . ostatnia linia poleceń ;;esac

Konstrukcja case próbuje znaleźć słowo ze wzorcem w pierwszej sekcji wzorca. Jeśli wyszukiwanie się powiedzie, program wykonuje wiersze poleceń po pierwszym wzorcu do odpowiednich znaków;;.

Jeśli pierwszy szablon nie zostanie znaleziony, następuje przejście do drugiego szablonu. Jeśli jakikolwiek wzorzec zostanie znaleziony, program nie bierze pod uwagę pozostałych wzorców, ale przechodzi do polecenia następującego po esac. Znak * jest używany jako wzorzec do dopasowania dowolnego słowa, a zatem daje zestaw poleceń do wykonania, jeśli nie zostanie znaleziony żaden inny wzorzec. Dlatego wzorzec gwiazdki (*) jest umieszczany jako ostatni wzorzec w konstrukcji przypadku, aby inne wzorce były sprawdzane jako pierwsze. Pomoże to wykryć nieprawidłowe i nieoczekiwane dane wejściowe.

Symbole wieloznaczne *, ?, . Zapewnia to elastyczność programu.

Rozważ przykład. Program set.term ustawia zmienną TERM zgodnie z typem używanego terminala. Używany jest następujący wiersz poleceń:

TERM=nazwa_terminala

Wzór * jest ostatnim na liście wzorów. Wysyła komunikat ostrzegawczy, że nie ma pasującego szablonu dla określonego typu terminala i umożliwia dokończenie konstrukcji przypadku.

$cat set.term echo Jeśli masz TTY 4420 wpisz 4420 echo Jeśli masz TTY 5410 wpisz 5410 echo Jeśli masz TTY 5420 wpisz 5420 przeczytaj termin wielkość liter w 4420) TERM-T4 ;; 5410) TERM-T5;; 5420) TERM-T7;; *) echo niepoprawny typ terminala ;; esac export TERM echo koniec programu $

9.3.8. Bezwarunkowe przekazanie kontroli

Polecenie przerwania bezwarunkowo zatrzymuje wykonywanie dowolnej pętli, w której występuje, i przekazuje sterowanie poleceniu następującemu po słowach kluczowych done, fi lub esac.

W poprzednim przykładzie programu set.term można użyć polecenia break zamiast echo, aby wyjść z programu, jak pokazano w poniższym przykładzie:

$cat set.term echo Jeśli masz TTY 4420 wpisz 4420 echo Jeśli masz TTY 5410 wpisz 5410 echo Jeśli masz TTY 5420 wpisz 5420 przeczytaj termin wielkość liter w 4420) TERM-T4 ;; 5410) TERM-T5;; 5420) TERM-T7;; *) złamać ;; esac export TERM echo koniec programu $

Polecenie Continue spowoduje, że program natychmiast przeskoczy do następnej iteracji pętli while lub for bez wykonywania pozostałych poleceń w pętli.

  • instruktaż

Podstawy BASH. Część 2.
Przepraszam za tak duże opóźnienie między artykułami, ale sesja daje o sobie znać w najbardziej nieodpowiednim momencie :)
Dziękuję wszystkim za komentarze, krytykę i uzupełnienia, które znalazły się w komentarzach do ostatniego artykułu.
Ta część, zgodnie z obietnicą, będzie poświęcona pętlom, operacjom matematycznym i wykorzystaniu poleceń zewnętrznych.
Zaczynajmy.

cykle. pętla for-in.

Operator for-in jest przeznaczony do uzyskiwania dostępu do wartości wymienionych na liście jeden po drugim. Każda wartość z kolei na liście jest przypisana do zmiennej.
Składnia jest następująca:
dla zmiennej na liście_wartości
robić
zespoły
zrobione

Rozważ mały przykład:

#!/kosz/bash
dla i w 0 1 2 3 4 #zmiennej $i zostaną przypisane wartości od 0 do 4 włącznie
robić
echo "Numer konsoli to $i" >> /dev/pts/$i #Zapisz ciąg "Numer konsoli to $i" do pliku /dev/pts/$i
zrobione #cykl zakończony
wyjście 0

Po wykonaniu przykładu na pierwszych 5 wirtualnych konsolach (terminalach) pojawi się linia z jej numerem. Wartości z listy są naprzemiennie podstawiane do zmiennej $i i praca z wartością tej zmiennej odbywa się w pętli

cykle. podczas pętli.

Pętla while jest bardziej złożona niż pętla for-in i służy do powtarzania poleceń, gdy niektóre wyrażenia są prawdziwe (kod powrotu = 0).
Składnia operatora jest następująca:
while wyrażenie lub polecenie, które zwraca kod powrotu
robić
zespoły
zrobione

Przykład działania pętli pokazano w poniższym przykładzie:

#!/kosz/bash
again=tak #przypisz ponownie wartość "tak" do zmiennej
while [ "$again" = "yes" ] #Będziemy zapętlać, aż $again będzie równe "tak"
robić
echo "Proszę podać nazwę:"
przeczytaj imię
echo "Wpisana nazwa to $name"

Echo "Czy chcesz kontynuować?"
Przeczytaj ponownie
zrobione
echo "Do widzenia"


A teraz wynik skryptu:
[e-mail chroniony]:~$ ./bash2_primer1.sh
Podaj nazwę:
ite
Wprowadzona nazwa to ite
Czy chcesz kontynuować?
tak
Podaj nazwę:
Michał
Wpisane imię to mihail
Czy chcesz kontynuować?
nie
PA pa

Jak widać, pętla jest wykonywana, dopóki nie wpiszemy czegoś innego niż „tak”. Pomiędzy zrobić i zrobić możesz opisać dowolne struktury, instrukcje itp., wszystkie zostaną wykonane w pętli.Ale powinieneś być ostrożny z tą pętlą, jeśli uruchomisz w niej jakiekolwiek polecenie bez zmiany zmiennej wyrażenia, możesz uzyskać w nieskończoną pętlę.
Przejdźmy teraz do warunku prawdy. Po chwili, tak jak w instrukcji warunkowej if-then-else, możesz wstawić dowolne wyrażenie lub polecenie, które zwraca kod powrotu, a pętla zostanie wykonana tak długo, jak kod powrotu = 0! Operator „[” jest odpowiednikiem polecenia test, które sprawdza prawdziwość przesłanego do niego warunku.

Spójrzmy na inny przykład, wziąłem go z książki Advanced Bash Scripting. Bardzo mi się podobało :), ale trochę to uprościłem. W tym przykładzie zapoznamy się z innym rodzajem pętli UNTIL-DO.. Jest to prawie kompletny odpowiednik pętli WHILE-DO, tylko że jest wykonywany, gdy jakieś wyrażenie jest fałszywe.
Oto przykład:

#!/kosz/bash
echo "Wpisz licznik: "
przeczytaj dywidendę
echo "Wpisz mianownik: "
przeczytaj dzielnik

dnd=$dividend #zmodyfikujemy zmienne dywidendy i dzielnika,
#zachowaj ich wiedzę w innych zmiennych, ponieważ oni nam dają
#potrzebować
dvs=$dzielnik
reszta = 1

Do [ "$reszta" -eq 0 ]
robić
niech „reszta = dzielnik % dywidendy”
dywidenda = $ dzielnik
dzielnik=$reszta
zrobione

Echo "gcd liczb $dnd i $dvs = $dywidenda"


Wynik wykonania skryptu:
[e-mail chroniony]:~$ ./bash2_primer3.sh
Wpisz licznik:
100
Wprowadź mianownik:
90
NWD liczb 100 i 90 = 10

Operacje matematyczne

niech komenda.
Polecenie let wykonuje operacje arytmetyczne na liczbach i zmiennych.
Rozważmy mały przykład, w którym wykonujemy obliczenia na wprowadzonych liczbach:
#!/kosz/bash
echo "Wpisz: "
czytać
echo "Wpisz b: "
przeczytaj b

Niech "c = a + b" #dodanie
echo "a+b= $c"
niech "c = a / b" #dziel
echo "a/b= $c"
niech „c<<= 2" #сдвигает c на 2 разряда влево
echo "c po przesunięciu o 2 bity: $c"
niech "c = a % b" # znajduje resztę z dzielenia a przez b
echo "$a / $b. reszta: $c "


Wynik wykonania:
[e-mail chroniony]:~$ ./bash2_primer2.sh
Wprowadź a:
123
Wpisz b:
12
a+b=135
a/b=10
c po przesunięciu o 2 bity: 40
123 / 12. reszta: 3

Cóż, jak widać, nic skomplikowanego, lista operacji matematycznych jest standardowa:
+ - dodawanie
- - odejmowanie
* - mnożenie
/ - dział
** - potęgowanie
% - modulo(dzielenie modulo), reszta z dzielenia
let pozwala na używanie skrótów poleceń arytmetycznych, zmniejszając w ten sposób liczbę używanych zmiennych. Na przykład: a = a+b jest równoważne a +=b itd.

Praca z programami zewnętrznymi podczas pisania skryptów powłoki

Zacznijmy od przydatnej teorii.
Przekierowanie strumienia.
Bash (i wiele innych powłok) ma wbudowane deskryptory plików: 0 (stdin), 1 (stdout), 2 (stderr).
stdout - Wyjście standardowe. Tutaj trafia wszystko, co wyprowadza programy.
stdin - wejście standardowe. To wszystko, co użytkownik wpisuje w konsoli
stderr — standardowe wyjście błędów.
Dla operacji na tych deskryptorach występują znaki specjalne: > (przekierowanie wyjścia),< (перенаправление ввода). Оперировать ими не сложно. Например:
przekieruj wyjście polecenia cat /dev/random do /dev/null (całkowicie bezużyteczna operacja :))) lub
zapisz zawartość bieżącego katalogu do pliku listingu (już bardziej przydatne)
Jeśli istnieje potrzeba dołączenia do pliku (w przypadku używania ">" jest on zastępowany), należy użyć ">>" zamiast ">"
po poproszeniu sudo o podanie hasła, zostanie ono pobrane z pliku my_password tak, jakbyś wprowadził je z klawiatury.
Jeśli potrzebujesz wpisać do pliku tylko błędy, które mogą wystąpić podczas działania programu, możesz użyć:
./program_z_błędem 2> plik_błędu
liczba 2 przed ">" oznacza, że ​​wszystko, co znajduje się w deskryptorze 2 (stderr), powinno zostać przekierowane.
Jeśli konieczne jest wymuszenie na stderr zapisu na stdout, można to zrobić w następujący sposób. sposób:
znak "&" oznacza wskaźnik do deskryptora 1 (stdout)
(Domyślnie stderr zapisuje do konsoli, w której pracuje użytkownik (bardziej prawdopodobne jest, że zapisze na wyświetlaczu)).
2. Przenośniki.
Potok jest bardzo potężnym narzędziem do pracy z konsolą Bash. Składnia jest prosta:
zespół1 | komenda 2 - oznacza, że ​​wyjście komendy 1 zostanie przekazane na wejście komendy 2
Potoki można grupować w łańcuchy i wyprowadzać za pomocą przekierowania do pliku, na przykład:
ls-la | grep "hash" |sort > sortilg_list
Wyjście polecenia ls -la jest przesyłane potokiem do polecenia grep, które wybiera wszystkie wiersze zawierające słowo hash, i przesyłane potokiem do polecenia sort, które zapisuje wynik w pliku lista_sortowania. Wszystko jest całkiem jasne i proste.

Najczęściej skrypty Bash są wykorzystywane jako automatyzacja niektórych rutynowych operacji w konsoli, stąd czasami konieczne staje się przetworzenie stdout jednego polecenia i przeniesienie go na stdin do innego polecenia, podczas gdy wynik wykonania jednego polecenia musi zostać przetworzony w w jakiś sposób. W tej sekcji postaram się wyjaśnić podstawowe zasady pracy z poleceniami zewnętrznymi wewnątrz skryptu. Myślę, że podałem wystarczająco dużo przykładów i teraz mogę napisać tylko główne punkty.

1. Przekazanie wyjścia do zmiennej.
Aby zapisać wyjście polecenia do zmiennej, wystarczy umieścić polecenie w cudzysłowie, na przykład
a = `echo "qwerty"`
echo $a

Wynik pracy: qwerty


Jeśli jednak chcesz zapisać listę katalogów do zmiennej, musisz odpowiednio przetworzyć wynik, aby umieścić dane w zmiennej. Rozważmy mały przykład:
LIST=`znajdź /svn/ -type d 2>/dev/null| awk "(FS="/") (wypisz $4)"| sortuj|uniq| tr "\n" " ""`
dla ONE_OF_LIST w $LIST
robić
svnadmin hotcopy /svn/$ONE_OF_LIST /svn/temp4backup/$ONE_OF_LIST
zrobione

Tutaj używamy pętli do zrobienia, aby zarchiwizować wszystkie katalogi w folderze /svn/ za pomocą polecenia svnadmin hotcopy (co nie ma znaczenia w naszym przypadku, tylko jako przykład). Najbardziej interesującą linią jest: LIST=`find /svn/ -type d 2>/dev/null| awk "(FS="/") (wypisz $4)"| sortuj|uniq| tr "\n" " "` W nim do zmiennej LIST przypisywane jest wykonanie polecenia find przetwarzanego przez polecenia awk, sort, uniq, tr (nie rozważymy wszystkich tych poleceń, ponieważ jest to osobny artykuł). Zmienna LIST będzie zawierać nazwy wszystkich katalogów w folderze /svn/ umieszczonych w jednej linii (w celu odpowietrzenia pętli.

Jak widać, wszystko nie jest trudne, wystarczy zrozumieć zasadę i napisać kilka własnych skryptów. Podsumowując, chciałbym życzyć powodzenia w nauce ogólnie BASH i Linuxa. Krytyka jak zwykle jest mile widziana. Następny artykuł będzie prawdopodobnie poświęcony korzystaniu z programów takich jak sed, awk.