W wykładzie 2 przedstawiono interpreter poleceń, tzn. narzędzie, które pośredniczy w kontaktach między użytkownikiem i systemem operacyjnym. Interpreter poleceń czeka na zlecenia użytkownika i przekazuje je systemowi operacyjnemu. Potrafi obsłużyć nie tylko proste wykonanie programów, ale także bardziej złożone instrukcje sterujące. W tym wykładzie nauczymy się posługiwać interpreterem oraz pisać skrypty poleceń interpretera.
Istnieje wiele tego typu programów (najstarszy Bourne-shell,
młodszy C-shell etc.). W trakcie tego wykładu przedstawimy interpreter
bash
.
Proponujemy czytelnikowi, aby na bieżąco wykonywał ćwiczenia dotyczące konstrukcji prezentowanych na wykładzie.
Można to robić na swoim komputerze lub na zdalnym serwerze. Jeśli mamy zainstalowany system Linux, to sprawa jest oczywista (wystarczy włączyć terminal). Jeśli zaś pracujemy na systemie Windows, to możemy podłączyć się do zdalnego serwera z systemem Linux lub zainstalować program o nazwie Cygwin, którego uruchomienie otworzy nam linuxową konsolę na systemie Windows.
mushelka.pjwstk.edu.pl
.
Więcej na ten temat można przeczytać
na stronie Bazy Systemowo-Sprzętowej.Gdy użytkownik loguje się w systemie, system operacyjny uruchamia dla niego interpreter poleceń. Użytkownik widzi wtedy znak zachęty interpretera, np.
bash$ _Może teraz wpisać nazwę programu, co spowoduje jego uruchomienie:
bash$ date <ENTER> Fri Feb 28 13:34:34 MET 2003 bash$ _
Interpreter poleceń jest zwykłym programem wykonywanym w ramach systemu
operacyjnego. Ten, z którego korzystamy na tych zajęciach, nosi nazwę
bash
i dokładnie tak brzmi polecenie, które go uruchamiania.
Można go więc też uruchomić z poziomu interpretera
poleceń. Wtedy zaczniemy korzystać z owego nowouruchomionego interpretera
poleceń:
bash$ bash <ENTER> bash$ date <ENTER> Fri Feb 28 13:34:34 MET 2003 bash$ exit <ENTER> bash$ _
Poprzedni przykład jest oczywiście nieciekawy, ponieważ działanie, takie jak powyżej
jest bezcelowe. Często wywołuje się jednak interpreter poleceń oddzielną instrukcją,
po to, żeby wykonał skrypt, tzn. ciąg poleceń interpretera zapisany w pliku.
Przypuśćmy, że w pliku skrypt1
umieszczono polecenie date
.
Wówczas ten skrypt można po prostu uruchomić (po nadaniu prawa do wykonywania tego
pliku poleceniem chmod u+x skrypt1
; szczegóły tego polecenia możesz znaleźć w
systemowym podręczniku użytkownika. Aby go przejrzeć wydaj polecenie man chmod
).
Uruchomienie programu wygląda następująco:
bash$ ./skrypt1<ENTER> Fri Feb 28 13:34:34 MET 2003 bash$ _Wykonanie polecenia
skrypt1
polega na (niejawnym) uruchomieniu
interpretera poleceń i przekazaniu mu do wykonania poleceń z pliku skrypt1
.
Można też jawnie uruchomić interpreter i przekazać mu skrypt z instrukcjami
do wykonania:
bash$ bash skrypt1<ENTER> Fri Feb 28 13:34:34 MET 2003 bash$ _Skrypty można też wywoływać z opcją
-x
. Przy takiej opcji
interpreter wypisuje polecenia, które wykonuje, np.:
bash$ bash -x skrypt1 + date Mon Mar 17 14:10:46 CET 2003 bash$ _
polecenie | opis |
---|---|
pwd | - wyświetla ścieżkę do katalogu, w którym aktualnie się znajdujemy |
cd | - przechodzi do katalogu podanego jako pierwszy argument |
ls | - wyświetla zawartość bierzącego katalogu (lub katalogu podanego jako argument) |
touch | - tworzy plik o podanej nazwie (jeśli plik już istnieje, to ustawia ostatnią datę użycia na bierzącą) |
cat | - zawartość podanych plików zwraca na standardowe wyjście (domyślnie jest nim terminal) |
mkdir | - tworzy katalog o podanej nazwie |
rm | - "usuwa" pliki/katalogi podane jako argumenty (dlaczego "" - dowiemy się jeszcze w tym wykładzie) |
cp | - plik podany jako pierwszy argument kopiuje do pliku podanego jako drugi argument |
mv | - zmienia nazwę pliku podanego jako pierwszy argument na nazwę podaną jako drugi argument |
man | - wyświetla podręcznik użytkownika do polecenia podanego jako argument (np. man cat) |
whoami | - wyświetla nazwę użytkownika, pod którą jesteśmy zalogowani w systemie (można też: echo "$USER" ) |
who | - wyświetla aktualnie zalogowanych użytkowników (można też wyświetlić w innym formacie: users ) |
man nano
Każdy program ma trzy podstawowe strumienie wejścia-wyjścia. Są to:
>
, za którym podajemy nazwę pliku, np.
bash$ ls -alR / > drzewokat.txt bash$ wc -l drzewokat.txt 557713 bash$ _Program
wc
podaje kolejno liczbę linii, słów i znaków w plikach podanych mu
jako argumenty (jeśli nie podamy żadnej nazwy pliku, to będzie liczył to co znajdzie na standardowym wejściu). Jeśli jako argument podamy mu flagę -l
, to zwróci nam tylko ilość linii w pliku. Jeśli podamy mu flagę -c
, to zwróci nam tylko ilość znaków.
Jeśli zamiast >
użyjemy >>
, to wynik programu
zostanie dodany na końcu pliku drzewokat.txt
, np.
bash$ ls -alR / > drzewokat.txt bash$ wc -l drzewokat.txt 557713 bash$ ls -alR / >> drzewokat.txt bash$ wc -l drzewokat.txt 1115426 bash$ ls -alR / >> drzewokat.txt bash$ wc -l drzewokat.txt 1673139 bash$ _Przy
>
plik, do którego przekierowujemy standardowe wyjście jest opróżniany
przed rozpoczęciem wykonywania instrukcji.
Możemy też zlecić, żeby program czytał dane z pliku zamiast z terminala. Wystarczy
w tym celu podstawić mu plik jako standardowe wejście za pomocą znaku
<
, za którym podajemy nazwę pliku, np.
bash$ cat > plik.txt ala ma kota ^D bash$ wc < plik.txt 3 5 23 bash$ _Najpierw za pomocą programu
cat
stworzyliśmy plik.txt
. Ten program po
prostu czyta standardowe wejście (albo pliki, których nazwy podano jako argumenty) i wypisuje
to, co przeczytał na standardowe wejście. Po uruchomieniu czekał on na dane, które mu wpisaliśmy
(ala ma kota
) i zakończyliśmy Unixowym znakiem końca pliku (control-D
).
Potem ten plik przekazaliśmy jako standardowe wejście do programu wc
, który policzył
odpowiednie statystyki.
Przekierowanie standardowego wyjścia diagnostycznego wykonujemy poprzez frazę
2>
, za którą podajemy nazwę pliku, np.
bash$ rm plik_ktorego_nie.txt 2> blad.txt bash$ cat blad.txt rm: cannot lstat `plik_ktorego_nie.txt': No such file or directory bash$ _Polecenie
rm
służy do usuwania plików (usuwa pliki o nazwach podanych jako argumenty).
rm
nie niszczy danych. Niszczony jest wyłącznie indeks wskazujący, gdzie jest przechowywany plik, a miejsce jest udostępniane do ponownego wykorzystania.
Należy wiedzieć, że istnieją narzędzia, które pozwalają odzyskać tak "usunięte" dane. Do niszczenia poufnych danych powinno się używać np. narzędzia shred
.
W podręczniku użytkownika programu shred (man shred
) czytelnik znajdzie więcej informacji na temat niszczenia danych.
sort
sortuje leksykograficznie linie plików podanych jako argumenty (lub dane podane na standardowe wejście), a polecenie uniq
usuwa powtarzające się sąsiednie linie, moglibyśmy napisać:
bash$ sort pl.txt > wynik1 bash$ uniq < wynik1 > wynik2 bash$ wc -l < wynik2
Istnieje prostsza (i szybsza, bo nie wymagająca wielokrotnego wykonania operacji zapisania/odczytania danych z dysku) metoda realizowania tego zadania.
Standardowe wyjście jednego programu można przekazać na standardowe wejście innego programu za pomocą znaku |
, np.
bash$ sort pl.txt | uniq | wc -lOstatecznie otrzymujemy tu liczbę różnych linii w pliku
pl.txt
.
Taki potok może mieć dowolną długość i wykonywać całkiem niebanalne zadania
Polecenie można wykonać w tle. Wówczas interpreter poleceń uruchamia odpowiedni
program i pozwala użytkownikowi na wprowadzanie następnych poleceń. Aby uruchomić polecenie
w tle, należy na jego końcu dodać znak &
, np.
bash$ ls -alR / > drzewokat.txt & [1] 10622 bash$ _Polecenie
ls
wypisuje informacje o wskazanych plikach. W tej postaci
szukamy plików od korzenia systemu (/
), wszystkich plików (tzn. włącznie z plikami ukrytymi, opcja a
),
rekurencyjnie (opcja R
) i z wypisaniem wyniku w długim formacie (opcja l
).
Wynik jest przesyłany do pliku drzewokat.txt
(por. Przekierowanie wejścia-wyjścia).
Oczywiście program wykonywany w tle nie powinien korzystać z terminala.
Jak widać system od razu umożliwia wpisanie następnego polecenia.
W wykładzie 2 przedstawiono interpretator poleceń. Jest to program, za którego pomocą uruchamia się inne programy. Szczególnie istotna jest możliwość przetwarzania potokowego i przekierowania standardowego wejścia-wyjścia. Bash ma wbudowany język skryptowy o sile pełnego języka programowania. Są w nim zmienne, wyrażenia arytmetyczne, logiczne, sterowanie, podprogramy i rekurencja. W kolejnych wykładach nauczymy się korzystać ze skryptów.
$1
, $2
, ..., $9
,
$@
i $#
.
cat ../kot
?
cat /etc/shadow 2>&1 | wc -l