SK Zadanie 2From Łukasz Graczykowski(Difference between revisions)
Revision as of 10:50, 13 October 2016Powłoka BashBash jest jedną z powłok systemowych, czyli programów, które pośredniczą między systemem operacyjnym a użytkownikiem. Użytkownik za pomocą powłoki uruchamia programy, jak i programy zwracają do powłoki wynik swojego działania, który następnie jest przekazywany użytkownikowi. Programy mogą komunikować sie z użytkownikiem również niezależnie (np. programy okienkowe). Każda powłoka zawiera polecenia, które wykonują podstawowe operacje w systemie operacyjnym (np. tworzenie folderów). Paletę domyślnych poleceń wzbogacają zewnętrzne programy, które wykonują operacje nie będące zawartymi poleceniami. Praktycznie każda dystrybucja Linuxa (z Androidem włącznie) zawiera powłokę Bash.
Powłoka Bash: PodstawyJednym z podstawowych poleceń jest echo foo foo W poleceniu echo możemy również stosować tzw. metaznaki. Przykładem takiego znaku jest cd / echo * bin boot dev etc home initrd.img initrd.img.old lib lib32 lib64 lost+found media mnt opt optl proc root run sbin selinux srv sys tmp usr var vmlinuz vmlinuz.old echo b* bin boot W powyższym przykładzie widzimy, że Bash rozwija znak Innym przykładem metaznaku jest echo ~ /home/jb
Zadanie 1Za pomocą polecenia
Powłoka Bash: Przekierowania i Potoki
Program cat nazwa_pliku
By przekierować standardowe wyjście programu do pliku należy użyć operatora cat plik1 plik2 >> polaczonepliki W wariancie z
Załóżmy, że mamy dwa polecenia: polecenieB i polecenieB i chcemy, aby polecenieB na swoje standardowe wejście przyjęło wynik działania polecenieA. W takim przypadku należy wpisać: polecenieA | polecenieB
Program tail okazuje koncówkę pliku cat /usr/share/romeo | tail -n 100
Program head pokazuje początek pliku
Każdy program ma podłączone dwa standardowe strumienie wyjściowe:
Rozróżnienie wynika z tego, aby wynik działania programu mógł być zwracany przez jeden strumień (np. polecenie tar zwróci spakowany folder), a informacje o ewentualnych błędach przez inny strumień. By przekierować standardowy strumień błędów należy użyć
> Zapisuje wynik działania do pliku. >> Dodaje wynik działania do pliku. 2> Przekierowuje strumień błędów. | Przesyła wynik działania (ang. output) programu na wejście (ang. input) drugiego programu. Więcej informacji: http://ryanstutorials.net/. Zadanie 2Proszę pobrać tekst Romeo i Julii po angielsku pg1112.txt wget http://www.gutenberg.org/cache/epub/1112/pg1112.txt Po kolei należy:
Pliki specjalnePlik /dev/null to plik, który przyjmuje dowolne dane, które potem znikają. Jest on przydatny kiedy chcemy się pozbyć jakiegoś strumienia danych (np. komunikatów o błędach). polecenie 2> /dev/null Plik /dev/random oraz /dev/urandom zawierają nieskończone ciągi losowych liczb. Taka komenda pozwala na wpipsanie kilku losowych znaków: cat /dev/urandom | head -c 66 | base64 SygnałySygnały są metodą na komunikację między procesami w systemach Linux’owych. Pozwalają, na przykład, na:
Polecenie kill przyjmuje id procesu, polecenie pkill wysyła sygnał do procesów, których nazwa zawiera ciąg znaków podanych w tym poleceniu. jb /tmp/bar $ ps -e | grep iceweasel 5020 ? 00:13:16 iceweasel kill 5020 To samo zadanie wykona: pkill iceweasel Domyślnie pkill i kill wysyłają sygnał TERM, który prosi proces by ten się wyłączył (proces może się na to nie zgodzić). Polecenia pkill -9 oraz kill -9 pozwalają na zabicie procesu (proces zawsze się wyłączy). Polecenie pkill --signal SIGSTOP spowoduje wstrzymanie wykonania procesu, a pkill --signal SIGCONT włączy go ponownie. Zadanie 3Proszę uruchomić przeglądarkę iceweasel, wstrzymać ją a następnie wznowić jej proces. Zmienne w BashW Bash’u można również tworzyć zmienne. jb@gautama:/$ foo="bar"; jb@gautama:/$ echo $foo; bar jb@gautama:/$ echo ${foo}; #Równoważne do $foo bar Uwaga: Białe znaki mają znaczenie: tj. poniższy kod jest niepoprawny: foo = "bar" Export powoduje, że zmienne są dostępne dla podprocesów. export foo="bar"; Nie ma możliwości udostępnienia zmiennych dla nadprocesów. By ustawić zmienne środowiskowe ‘na stałe’ należy umieścić odpowiednie polecenia export w plikach: /etc/bash.bashrc wtedy zmienne będą widoczne dla wszystkich użytkowników ~/.bashrc wtedy będą widoczne dla danego użytkownika. Zmienna pathZmienna path jest magiczną zmienną powłoki BASH, pozwala ona na zdefiniowanie w jakich katalogach bash szuka plików wykonywalnych. Note Zmienna $PATH określa listę katalogów, które będą przeszukiwane podczas uruchamiania programu. Jeśli $PATH to /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games oznacza to, że po wykonaniu polecenia np. nano zostaną przeszukane takie położenia: /usr/local/bin/nano, /usr/bin/nano. itp. Wszystkie zmienne środowiskowe można wyświetlić za pomocą polecenia printenv. Zadanie 4Proszę ustawić zmienną PATH na pusty ciąg znaków i sprawdzić jakie polecenia działają. Czy działa:
Polecenia, które działają są wbudowanymi poleceniami powłoki bash, pozstałe są programami. CytowaniePowiedzmy, że mamy katalog o nazwie Moje Dokumenty, który znajduje się w bieżącym katalogu. Chcemy go usunąć, jednak nie udaje się to: rm Moje Dokumenty rm: cannot remove ‘Moje’: No such file or directory rm: cannot remove ‘Dokumenty’: No such file or directory Okazuje się, że bash potraktował Moje Dokumenty jako dwa katalogi, jeden o nazwie Moje, drugi o nazwie Dokumenty. By usunąć ten plik należy użyć cytowania, czyli powiedzieć bashowi: ten ciąg znaków ze spacją jest jednym słowem, służą do tego podwójne cudzysłowy. Taka komenda zadziała: rm "Moje Dokumenty" Powiedzmy, że nasz skrypt chce wyświetlić użytkownikowi napis: Dodaj katalog foo do zmiennej ${PATH}. Polecenie: echo "Dodaj katalog foo do zmiennej ${PATH}" wyświetli: Dodaj katalog foo do zmiennej /usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games Znów musimy zacytować nasz ciąg znaków, ale tym razem trzeba użyć pojedyńczego apostrofu: echo 'Dodaj katalog foo do zmiennej ${PATH}' Wyświetla: Dodaj katalog foo do zmiennej ${PATH} Linia hashbangSkrypty bash mogą być uruchamiane tak samo jak zwykłe programy, o ile: nadano im uprawnienia do wykonywania chmod +x nazwa.sh rozpoczynają się od linii hashbang, czyli od: #!/bin/bash, w linii tej po znakach #! znajduje się pełna ścieżka do interpretera, który wykona ów program. Przykład najprostszego skryptu: #!/bin/bash echo hello ze skryptu Zadanie 5Napisać skrypt, który wypisze 3 linijki: Ścieżka do Twojego katalogu domowego (np. /home/foo) (skorzystać z odpowiedniej zmiennej środowiskowej) ${HOME} (w konsoli ma się pojawić dokładnie taki napis) aktualna data to: pon, 9 mar 2015, 17:47:38 CET (skorzystać z polecenia date)
Zapisywanie wyniku polecenia w zmiennejCzasem chcemy zapisać wynik polecenia do zmiennej, np. polecenie date wyświetla do wyświetlania daty służy polecenie date: date +%Y-%m-%d wyświetla: 2015-10-05 Chcemy stworzyć plik o nazwie kopia-zapasowa-data: curr_date=$(date +%Y-%m-%d) file_name="kopia-zapasowa-${curr_date}" echo > $file_name można to zrobić prościej: touch "kopia-zapasowa-$(date +%Y-%m-%d)" Note Uwaga! Działanie $() można osiągnść również poprzez zastosowanie odwróconych cudzysłowów (`), tj: touch "kopia-zapasowa-`date +%Y-%m-%d`" Jednak by oszczędzić Wam problemów z , ‘ oraz ”, będę wykorzystywał ``$()`. Specjalne zmienneSkrypt basha zawiera specjalne zmienne:
Zadanie 7Napisać skrypt (i uruchomić z 3. dowolnymi argumentami), który:
Instrukcje warunkoweWykonanie każdego programu może skończyć się albo sukcesem, albo porażką, do syngalizowania sukcesu lub porażki służy tzw. kod wyjścia. Note W C kod wyjścia programu jest sygnalizowani (między innymi) wartością zwracaną przez funkcję main. Jeśli program wykonmał się poprawnie funkcja zwraca 0, jeśli nie poprawnie inną wartość. Note Jest to notacja odwrotna od tej stosowanej w C, tam 0 oznacza fałsz, a 1 prawdę. Powód takiej notacji w jest prosty: Program może poprawnie się wykoanć tylko w jeden sposób, może natomiast napotkać na wiele problemów, które spowodują błędne wykonanie. Do sprawdzenia kodu wyjścia ostatniego polecenia można użyć magicznej zmiennej $?. Instrukcja if w Bash ma następującą składnię: if warunek then fi Gdzie warunek jest dowolnym programem. Jeśli program ten zwróci kod wyjścia 0 warunek się wykona, nie wykona się natomiast jeśli zwróci inny kod wyjścia.
then echo "Jest" fi Note Uwaga zastosowałem tu nową składnię polecenia grep jest to składnia grep wzorzec nazwa pliku oraz przekierowałem wyjście z grep do pliku Pełna składnia if jest taka:
if warunek1 then polecenie1 elif warunek2 then polecenie2 else polecenie3 fi W warunku if często korzysta się z polecenia test, na przykład if test -e /tmp/foo then echo istnieje else echo nie istnieje fi Polecam sprawdzenie jak działa polecenie test za pomocą man test. Polecenie test można wykorzystać również za pomocą krótszej postaci, tj. nawiasów kwadratowych: if [ -e /tmp/foo ] then echo istnieje else echo nie istnieje fi Uwaga: między [ oraz ], a warunkiem musi znajdować się przynajmniej jedna spacja. Zadanie 8Napisać skrypt, który: sprawdzi czy istnieje plik porówna liczbę plików w katalogu głównym oraz domowym i wypisze odpowiednią informację Note Polecam program wc (proszę przeczytać man wc) Obliczenia arytmetyczne Do obliczeń arytmetycznych służy funkcja let: let x=10 echo $x # wypisze 10 let "x /= 3" echo $x # wypisze 3 let "x *= x" echo $x # wypisze 9 Warning Bash może wspierać tylko arytmetykę stałoprzecinkową, dla której 10/3 wynosi dokładnie 3. Warning Przy wykonywaniu operacji należy umieszczać spacje wokół operatora =. FunkcjeNiektóre fragmenty skryptu można zamknąć w funkcję, składnia funkcji jest następująca: function func { # Treść } By wykonać funkcję należy napisać jej nazwę. Do funkcji można przekazywać parametry. Parametry funkcji są dostępne za pomocą tych samych zmiennych co argumenty skyptu, tj:
PętlePętla for pozwala na iterowanie po zbiorze elementów separowanych spacją: for i in a b c d do echo "wartość iteratora to $i" done for i in /etc/*conf do echo "$i" done Note Można skonfigurować basha tak, by separatorem był inny znak, ale poprzestańmy na spacji. while - sprawdza, czy warunek jest prawdziwy, jeśli tak, pętla wykonuje się, aż warunek stanie się fałszywy: a=0 while [ $a -lt 5 ] do echo "pętla wykonuje się po raz: $a" a=$[a + 1] # lub a=$(( $a + 1 )) done until - sprawdza, czy warunek jest fałszywy, jeśli tak, pętla wykonuje się aż warunek stanie się prawdziwy: a=0 until [ $a -gt 5 ] do echo "pętla wykonuje się po raz: $a" a=$[a + 1] done Zadanie 9Napisz funkcję, która liczy silnię jej argumentu, wykonaj ją dla liczb od 1 do 15. Zadania i informacje dodatkoweProszę wylistować użytkowników z pliku Note Polecenie |