Wszystko o konsoli

Druga część poradnika: Konsola dla Eksperta


"Ta książka stanowi zbiór dodatków i aneksów. I nie sposób przewidzieć, jak obszerne będzie następne uzupełnienie ani gdzie zostanie wstawione. W żadnym momencie nie mogę uznać jej za ukończoną ani nieukończoną"
Aleksander Sołżenicyn


Przewodnik ten jest wprowadzeniem do powłok uniksowych. Ze względu na obszerny zakres materiału, nie porusza on wszystkich zagadnień. Będzie on systematycznie rozbudowywany, zapraszam wszystkich do edycji w Wiki. Ze względu na fakt, że niemal każde zadanie w systemach uniksowych można wykonać na co najmniej kilka sposobów, prezentowanych przykładów proszę nie traktować jako prawdy ostatecznej.

1. Dlaczego warto korzystać z konsoli?

Istnieje wiele powodów, dla których warto zapoznać się z możliwościami oferowanymi przez uniksową konsolę. Korzystając z trybu tekstowego, czerpiemy z ponad 30 letniego dorobku najlepszych hakerów uniksowych. Warto pamiętać, że programy które są łatwe w nauce, nie zawsze cechują się największą użytecznością. Więcej powodów dlaczego warto korzystać z konsoli, można przeczytać w artykule o konsoli.
Oczywiście konsola ma też wady. Brak jest programów do obróbki multimediów — tekstowy charakter pracy w konsoli praktycznie uniemożliwia tego typu pracę.

2. Czym jest powłoka, czym jest terminal, czym jest konsola?

Bardzo często pojęcia te używane są zamiennie do opisania trybu tekstowego. W obecnych czasach rzeczywiście różnice pomiędzy nimi się zacierają. Pojęcia te wywodzą się z czasów, kiedy komputery osobiste nie były jeszcze tak popularne a Unix królował na maszynach typu mainframe. Terminal jest to urządzenie pozwalające człowiekowi na pracę z komputerem. Umożliwia on wprowadzanie instrukcji do wykonania oraz wyprowadzanie wyników pracy komputera.W zamierzchłych czasach rolę terminala pełnił dalekopis i drukarka. Z czasem wprowadzono ekran komputerowy i klawiaturę. Mianem konsoli określano terminal, na którym pracował administrator systemu. W tym miejscu warto nadmienić, że budowa terminali, dostępność do sprzętu oraz jego koszta miały olbrzymi wpływ na kształtowanie się Uniksa. Pierwsze terminale nie były za szybkie stąd też programiści musieli tworzyć programy, które były zwięzłe i nie produkowały zbyt dużo danych na wyjściu. W ten sposób powstała reguła KISS (Keep it simple stupid!), która oznacza dążenie do prostych rozwiązań. Programy pobierają dane i wprowadzają je w postaci zwykłego tekstu dzięki czemu polecenia można łączyć za pomocą potoków, można przekierować je do i z pliku za pomocą przekierowań z wykorzystaniem potęgi wyrażeń regularnych.
Ostatnim pojęciem jest pojęcie powłoki (ang. shell), zwanej też interpreterem. Powłoka stanowi swoisty interfejs pomiędzy użytkownikiem a jądrem systemu operacyjnego tworząc środowisko do uruchamiania i obsługi programów. Wyróżnia się dwa rodzaje powłok: graficzne takie jak np. Explorer znany z Windows lub finder z Mac OS, oraz tekstowe takie jak np. bash, sh, tcsh.

3. Bash

Bash jest jedną z wielu powłok dostępnych w systemach z rodziny Unix. Zwana też jest 'Bourne again shell' na cześć Stevena Bourna, twórcy klasycznej powłoki sh. Bash jest wstecznie kompatybilny z powłoką sh. Jedną z ważnych cech każdej powłoki jest fakt, że większość poleceń jest tak naprawdę samodzielnymi programami, które znajdują się w drzewie katalogów. Sam bash też jest programem, który w Linuksie znajduje się w lokalizacji /bin/bash (w Solarisie w /usr/bin/bash, we FreeBSD i OpenBSD w /usr/local/bin/bash). Część poleceń wbudowana jest w powłokę np. cd, break, exec.
Powłoki wykorzystują intensywnie strumienie wejścia/wyjścia:

  • stdin — standardowy strumień wejścia, dostarczający informacje do komputera, domyślnie instrukcje pobierane są z klawiatury,
  • stdout — standardowy strumień wyjścia, na który wyprowadzane są dane wyjściowe komputera, domyślnie jest to ekran monitora,
  • stderr — standardowy strumień błędów, wyprowadzane są na niego błędy jakie napotka program w czasie działania, standardowo jest to ekran monitora.

Sesja z powłoką bash na koncie zwykłego użytkownika wygląda tak, jak pokazano poniżej. Jako tzw. znak zachęty używany jest symbol $. Po znaku zachęty użytkownik może wpisywać polecenia.

adz@laptop:~$
[adz@laptop /]$
$

W przypadku pracy na koncie administratora (ang. root), jako znak zachęty używany jest symbol #.
root@laptop:~#
[root@laptop /]#
#

Żaden z przedstawionych przykładów nie będzie wymagał uprawnień administratora, chyba że będzie wspomniane to wcześniej.

4. Zarządzanie plikami

Systemy uniksowe zapewniają szereg poleceń służących do manipulowania plikami oraz katalogami. Ich mocną stroną jest fakt, że w miarę prosty sposób można ich użyć na grupie plików/katalogów, spełniających określone wymagania. Na przykład można usunąć wszystkie pliki, które spełniają określone kryteria lub dokonać masowej zmiany nazw.

4.1. ls

ls to bardzo często wykorzystywane polecenie. Wyświetla ono na standardowym wyjściu zawartość katalogu. Jeżeli jako parametr nie poda się ścieżki do katalogu, wyświetlona zostanie zawartość katalogu bieżącego (tj. tego, w którym aktualnie się znajdujemy).

adam@laptop:~/Dokumenty/jakilinux.org$ pwd
/home/adam/Dokumenty/jakilinux.org/
adam@laptop:~/Dokumenty/jakilinux.org$ls
przykład.txt  wszystko_o_konsoli.txt
adam@laptop:~/Dokumenty/jakilinux.org$ls /var/
backups  cache  crash  games  lib  local  lock  log  mail  opt  run  spool  tmp

W drugim przykładzie powyżej została wyświetlona zawartość katalogu podanego jako parametr. Polecenie ls może wyświetlać bardziej szczegółowe dane, jeżeli uruchomi się je z parametrem -l.
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls -l
razem 0
-rw-r--r-- 1 adam adam 0 2007-05-30 11:31 przykład.txt
-rw-r--r-- 1 adam adam 0 2007-05-30 11:31 wszystko_o_konsoli.txt

W powyższym listingu w pierwszej linii wyświetlana jest suma bloków na dysku użytych przez pliki w katalogu. Dalej wyświetlane są:
  • -rw-rr uprawnienia danego pliku, katalogu (szerzej na temat uprawnień w dalszej części przewodnika),
  • liczba twardych dowiązań do danego pliku,
  • właściciel pliku, grupa do której należy właściciel,
  • długość pliku,
  • data ostatniej modyfikacji,
  • nazwa pliku/katalogu.

Polecenie ls umożliwia wyświetlanie plików ukrytych (tzw. pliki z kropką). Pliki ukryte zaczynają się od znaku kropki ., do wyświetlania plików ukrytych służy parametr -a.

adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls -a
.  ..  .plik_ukryty  przykład.txt  wszystko_o_konsoli.txt

Polecenie ls umożliwia sortowanie wyników. Do dyspozycji są parametry:
  • -t — wyświetla zawartość posortowaną wg daty modyfikacji (od najnowszej do najstarszej),
  • -S — wyświetla zawartość wg rozmiaru od największego do najmniejszego,
  • -r — odwraca porządek sortowania.

Istnieje również możliwość wyświetlenia rekursywnego zawartości katalogów, tzn. wyświetlona zostanie zawartość wszystkich podkatalogów w katalogu, służy do tego parametr -R.

adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls -R 
.:
katalog1  katalog2  przykład.txt  wszystko_o_konsoli.txt

./katalog1:
plik1  plik2

./katalog2:
plik3  plik4

4.2. cd

Polecenie cd (ang. change directory) służy do poruszania się po drzewie katalogów. Jako parametr polecenie pobiera miejsce w drzewie katalogów, do którego chcemy się przenieść.

adam@laptop:~$cd /usr/bin
adam@laptop:/usr/bin$pwd
/usr/bin

W tym miejscu warto nadmienić, że znak ~ (tylda) jest traktowany przez powłokę jako znak specjalny — jest to skrót do katalogu domowego (ang. home directory) użytkownika.
adam@laptop:/usr/bin$cd ~
adam@laptop:~$pwd
/home/adam

Jeżeli wpiszemy cd ~nazwa_użytkownika, to polecenie to przeniesie nas do katalogu domowego użytkownika o loginie nazwa_użytkownika.
adam@laptop:~$cd ~zoidberg
adam@laptop:/home/zoidberg$pwd
/home/zoidberg

Znak - oznacza katalog, który był poprzednio katalogiem roboczym. Aby przejść do katalogu nadrzędnego, należy wpisać cd .. Każdy (nawet pusty) katalog w systemach uniksowych zawiera 2 elementy . i .. Pojedyncza kropka . jest to dowiązanie katalogu do niego samego, natomiast dwukropek .. jest dowiązaniem do katalogu nadrzędnego w drzewie katalogów.
adam@laptop:~$cd ..
adam@laptop:/home$pwd
/home

Wraz z poleceniem cd, warto wprowadzić terminy ścieżka względna i ścieżka bezwzględna.
  • Ścieżka bezwzględna (zwana też absolutną, ang. absolute path) to ścieżka, która rozpoczyna się od korzenia drzewa katalogów / np. /home/adam.
  • Ścieżka względna (ang. relative path) to ścieżka rozpoczynająca się od katalogu, w którym obecnie się znajdujemy.

4.3. mkdir, rmdir

Polecenia te służą odpowiednio do tworzenia i usuwania katalogów. Jako parametr podajemy nazwę tworzonego/usuwanego katalogu. Poleceniem {rmdir} można usunąć tylko pusty katalog.

adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ mkdir katalog
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls
katalog  przykład.txt  wszystko_o_konsoli.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ rmdir katalog/
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls
przykład.txt  wszystko_o_konsoli.txt

4.4. cp, mv, rm

  • {cp} — polecenie to służy do kopiowania plików, pobiera ono co najmniej dwa parametry: plik źródłowy i miejsce docelowe, do którego chcemy go skopiować,
  • mv — służy do przenoszenia lub zmiany nazwy plików lub katalogów, działa na identycznej zasadzie jak polecenie cp,
  • rm — służy do usuwania plików.

Polecenia cp, mv i rm mają następujące wspólne parametry:

  • -f force — wymusza usuniecie docelowego pliku, nawet w przypadku braku uprawnień do zapisu,
  • -i interactive — użytkownik zostanie poproszony o potwierdzenie wykonywanej operacji,
  • -b —backup — zostanie utworzona kopia zapasowa plików nadpisywanych (tylko cp i mv),

Polecenia cp i rm mogą również pracować w trybie rekursywnym, umożliwia to parametr -r (-R, —recursive).

adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls
katalog1  katalog2  katalog3  przykład.txt  wszystko_o_konsoli.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ cp -R katalog2/ katalog3/
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls katalog3/
katalog2
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ rm -r katalog3/
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls 
katalog1  katalog2  przykład.txt  wszystko_o_konsoli.txt

Poleceniem rm -r można usuwać niepuste katalogi, tak jak na przykładzie powyżej.

4.5. ln

Jest to polecenie wykorzystywane do tworzenia dowiązań do plików, dowiązania można interpretować jako odpowiednik skrótu do pliku znanego z systemów Windows (jest to trochę naciągana interpretacja!)
Wyróżniamy dwa rodzaje dowiązań:

  • miękkie (tzw. symboliczne), odwołują się one do pliku — ten rodzaj dowiązań można interpretować jako odpowiednik skrótu z Windows,
  • twarde — jest to dowiązanie do konkretnego miejsca na dysku, innymi słowy do fizycznego obszaru na dysku gdzie znajduje się plik.

Jeżeli usunie się plik, do którego prowadzi dowiązanie symboliczne, dowiązanie to zostanie podświetlone na czerwono (jeżeli powłoka wspiera kolory), jeżeli usuniemy plik, do którego utworzone zostało dowiązanie twarde, nic się nie stanie, taki plik zostanie usunięty dopiero wtedy, gdy liczba twardych dowiązań spadnie do zera.

Dowiązania symboliczne tworzy się uruchamiając polecenie ln z parametrem -s.

adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ cat plik 
Przykład dowiązań.
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ln -s plik dowiazanie_symboliczne
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls -l 
lrwxrwxrwx 1 adam adam    4 2007-06-01 19:11 dowiazanie_symboliczne -> plik
-rw-r--r-- 1 adam adam   22 2007-06-01 19:10 plik
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ rm plik 
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls
dowiazanie_symboliczne  (w tym przypadku tekst wyświetlony jest na czerwono wskazując błąd)

W powyższym przykładzie można zaobserwować działanie dowiązań symbolicznych. Polecenie ls wskazuje, że dla pliku nie zmieniła się liczba twardych dowiązań. Zupełnie inaczej jest na przykładzie poniżej, gdzie liczba twardych dowiązań wynosi 2, po usunięciu pliku spada do 1, plik cały czas jest dostępny.
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ln plik dowiazanie_twarde
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls -l
-rw-r--r-- 2 adam adam   22 2007-06-01 19:11 dowiazanie_twarde
-rw-r--r-- 2 adam adam   22 2007-06-01 19:11 plik
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ rm plik 
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls -l
-rw-r--r-- 1 adam adam   22 2007-06-01 19:11 dowiazanie_twarde

4.6. touch

touch to proste polecenie mające dwa zastosowania. Jeżeli podamy jako parametr istniejący plik, to zmieni mu datę modyfikacji. Jeżeli podamy nazwę nieistniejącego pliku, to zostanie utworzony pusty plik.

adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls -l przykład.txt 
-rw-r--r-- 1 adam adam 0 2007-05-30 11:31 przykład.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ touch przykład.txt 
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls -l
razem 0
-rw-r--r-- 1 adam adam 0 2007-06-07 13:27 przykład.txt
-rw-r--r-- 1 adam adam 0 2007-05-30 11:31 wszystko_o_konsoli.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ touch nowy.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls -l
razem 0
-rw-r--r-- 1 adam adam 0 2007-06-07 13:28 nowy.txt
-rw-r--r-- 1 adam adam 0 2007-06-07 13:27 przykład.txt
-rw-r--r-- 1 adam adam 0 2007-05-30 11:31 wszystko_o_konsoli.txt

Uruchamiając touch z parametrem -c lub —no-create, zapobiegniemy utworzeniu nowego pliku.
Parametr -d lub -t przy czym parametr t wymaga określenia daty w formacie MMDDhhmm.
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls -l
razem 0
-rw-r--r-- 1 adam adam 0 2007-06-07 13:28 nowy.txt
-rw-r--r-- 1 adam adam 0 2007-06-07 13:27 przykład.txt
-rw-r--r-- 1 adam adam 0 2007-05-30 11:31 wszystko_o_konsoli.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls -l
razem 0
-rw-r--r-- 1 adam adam 0 2007-06-07 13:28 nowy.txt
-rw-r--r-- 1 adam adam 0 2007-06-07 13:27 przykład.txt
-rw-r--r-- 1 adam adam 0 2007-05-30 11:31 wszystko_o_konsoli.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ touch -t 200706101200 nowy.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ touch -d "last monday" przykład.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ touch -d "2 days ago 12:00" wszystko_o_konsoli.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls -l
razem 0
-rw-r--r-- 1 adam adam 0 2007-06-10 12:00 nowy.txt
-rw-r--r-- 1 adam adam 0 2007-06-04 00:00 przykład.txt
-rw-r--r-- 1 adam adam 0 2007-06-05 12:00 wszystko_o_konsoli.txt

4.7 df, du

Służą do wyświetlania miejsca zajmowanego przez system plików (df) oraz przez konkretny plik (du). Uruchomione z parametrem -h dadzą wyniki w bardziej zrozumiałych jednostkach. Przykład dla polecenia df:

adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ df -h
System plików            rozm. użyte dost. %uż. zamont. na
/dev/sda5              40G   34G  4,0G  90% /
varrun                502M  136K  502M   1% /var/run
varlock               502M     0  502M   0% /var/lock
procbususb            502M  148K  502M   1% /proc/bus/usb
udev                  502M  148K  502M   1% /dev
devshm                502M     0  502M   0% /dev/shm

Przykład dla polecenia du:
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ du -h error.txt 
4,0K    error.txt

4.8. echo

Jest to proste polecenie, które jako wynik swojej pracy zwraca tekst, który został podany mu jako parametr.

adam@laptop:~$echo Hello World!
Hello World!

Polecenie to dodaje na końcu znak przejścia do nowej linii, aby to ominąć, należy uruchomić program, z parametrem -n. Na przykład:
adam@laptop:~$echo -n Hello World!
Hello World!adam@laptop:~$

W przypadku zamknięcia tekstu w cudzysłowy, tekst będzie interpretowany bezpośrednio (o tym później).

4.9. pwd

pwd (ang. print working directory) to polecenie wyświetlające pełną ścieżkę w miejscu w drzewie katalogów, w którym aktualnie się znajdujemy.

adam@laptop:~$pwd
/home/adam

4.10. cat

Polecenie cat można wykorzystywać w celu tworzenia pliku a dokładniej rzecz ujmując przekierowania standardowego wejścia do pliku oraz wyświetlenia na standardowym wyjściu. Plik tworzy się w następujący sposób:

adam@laptop:~$cat > plik.txt
Bardzo ciekawy tekst.
<Ctrl+d>

Temat użycia operatora > zostanie poruszony szerzej w dalszej części przewodnika. Aby wyświetlić zawartość pliku, wystarczy wpisać cat nazwa_pliku.
adam@laptop:~$cat plik.txt
Bardzo ciekawy tekst.

Możesz również uzyskać numery linii wyświetlanego pliku w lewym rogu ekranu.
adam@laptop:~$cat -n plik.txt
     1  Bardzo ciekawy tekst.

Polecenie cat może również łączyć pliki, w poniższym przykładzie scalam 5 fragmentów obrazu ISO w jedną całość.
cat plik1 plik2 plik3 plik4 plik5 > file.iso

4.11. wc, head, tail

Te trzy polecenia wykorzystywane są do operacji na ciągach tekstu. Polecenie wc wyświetla liczbę linii, słów oraz bitów w danym pliku.

adam@laptop:~/Dokumenty/jakilinux.org$ wc wszystko_o_konsoli.txt
94  908 6828 wszystko_o_konsoli.txt

W powyższym przykładzie pierwsza kolumna to liczba linii, druga słów, a trzecia liczba bitów.
Kolejne dwa polecenia wyświetlają odpowiednio początek pliku (head) oraz koniec (tail) — domyślnie wyświetlane jest 10 linii tekstu. Wartość tę w obu programach można regulować parametrem -n podając liczbę linii, które chcemy zobaczyć.
adam@laptop:~/Dokumenty/jakilinux.org$ head -n 1 przykład.txt
Pierwsza linia tekstu!
adam@laptop:~/Dokumenty/jakilinux.org$ tail -n 2 przykład.txt
Przed ostatnia linia tekstu!
Ostatnia linia tekstu!

4.12 less

Polecenie less służy do przeglądania pliku z możliwością jego przewijania, zarówno do przodu, jak i wstecz.

adam@laptop:~$ less plik.txt

Powyższe polecenie spowoduje wyświetlenie pliku plik.txt. Wprowadzenie :f podczas korzystania z programu spowoduje wyświetlenie interesujących informacji, np. numer linii na górze ekranu czy wielkości pliku. Dodatkowo zastosowanie przełącznika -N umożliwia wyświetlenie numeru każdej linii przy lewej krawędzi ekranu, co widać poniżej.
adam@laptop:~$ less -N plik.txt

Program opuszczamy wpisując :q.

5. Strumienie, potoki i przekierowania

5.1. Potoki

Siłą konsoli systemów uniksowych jest możliwość łączenia małych zwięzłych poleceń w większe, bardziej skomplikowane polecenia, za pomocą potoków (ang. pipe). Dane na wyjściu jednego programu będą stanowić dane wejściowe drugiego programu. To właśnie dlatego w systemach uniksowych tak powszechnie wykorzystywane są tekstowe strumienie danych. Te założenia legły u podstaw filozofii Uniksa.
Polecenia łączy się za pomocą operatora | zwanego czasem w polskojęzycznej literaturze "rurą" (ang. pipe). W skrócie wygląda to następująco:

polecenie1 | polecenie2 | polecenie3

W przykładzie poniżej wyjście polecenia ls przekierowuję do polecenia wc z parametrem -l, dzięki czemu zostanie wyświetlona się liczba plików i katalogów w danym katalogu.
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls
nowy.txt  przykład.txt  wszystko_o_konsoli.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls | wc -l
3

Potoki wykorzystywane są intensywnie przypadkach takich jak przeszukiwanie logów systemowych z wykorzystaniem wyrażeń regularnych lub w wyszukiwaniu plików (o tym w dalszej części poradnika).

5.2. Strumienie i przekierowania

Tak jak wspominałem już na początku poradnika, powłoki w systemach uniksowych intensywnie wykorzystują strumienie: wejścia, wyjścia i błędów. Strumienie można przekierowywać z urządzenia, które standardowo je obsługuje na inne lub też do pliku, np. można przekierować komunikaty o błędach z monitora do pliku.
Każdy ze strumieni ma swój unikalny deskryptor oznaczany liczbowo:

  • stdout — standardowe wyjście (deskryptor 1) — przeważnie jest to monitor komputera,
  • stderr — standardowe wyjście błędów (deskryptor 2) — przeważnie jest to monitor komputera,
  • stdin — standardowe wejście (deskryptor 0) — przeważnie jest to klawiatura komputera.

Do przekierowania używa się operatora deskryptor>, gdzie za deskryptor podstawia się jedną z wartości liczbowych przedstawionych powyżej. Jeżeli plik, do którego przekierowujemy, nie istnieje, to zostanie utworzony (oczywiście o ile mamy uprawnienia do zapisu w danym katalogu). Jeżeli plik istnieje (i mamy uprawnienia do zapisu w nim), jego zawartość zostanie zastąpiona. Aby tego uniknąć, należy użyć operatora deskryptor», który dopisze zawartość strumienia na koniec pliku.
W poniższym przykładzie przekieruję standardowy strumień błędów do pliku error.txt, następnie przekieruję standardowe wejście do pliku i na koniec przekieruję standardowe wejście z klawiatury do pliku.

adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ cat nieistniejacy_plik.txt 2> error.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ cat error.txt 
cat: nieistniejacy_plik.txt: No such file or directory
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ cat > polecenie.txt
ls -l
(Ctrl+D)
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ bash < polecenie.txt
razem 8
-rw-r--r-- 1 adam adam 55 2007-06-26 14:04 error.txt
-rw-r--r-- 1 adam adam  0 2007-06-10 12:00 nowy.txt
-rw-r--r-- 1 adam adam  5 2007-06-26 14:07 polecenie.txt
-rw-r--r-- 1 adam adam  0 2007-06-04 00:00 przykład.txt
-rw-r--r-- 1 adam adam  0 2007-06-05 12:00 wszystko_o_konsoli.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$

Przekierowania dość powszechnie wykorzystywane są w przypadku zadań uruchamianych w tle, kiedy nie ma potrzeby przeglądania komunikatów programu na bieżąco. Warto również wspomnieć o tym, jak całkowicie pozbyć się komunikatów.
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ cat nieistniejacy_plik.txt 2> /dev/null

Ponieważ wszystkie urządzania w Uniksie są reprezentowane jako pliki, istnieje możliwość takiego przekierowania jak powyżej, innymi słowy wszystkie komunikaty błędów trafiły do śmietnika czyli urządzenia /dev/null.

5.3. xargs

Poleceniem, którego działanie wiąże się z ideą strumieni i potoków, jest polecenie xargs. Otrzymuje ono na wejściu strumień tekstu i rozdziela go wg kryteriów (znak null lub znak końca wiersza) i następnie tak rozdzielone fragmenty przekazuje po kolei jako argumenty do kolejnego polecenia. xargs jest bardzo często wykorzystywany w połączeniu z poleceniami find, locate i grep.

adam@laptop:~$ ls | grep raport | xargs -i cp {} Dokumenty/

W powyższym przykładzie zastosowano polecenie grep, które szerzej zostanie omówione później. Wszystkie pliki, zawierające w nazwie ciąg znaków raport, zostaną przekopiowane do katalogu Dokumenty, dzięki zastosowaniu opcji -i, nawiasy {} zastępowane są fragmentem strumienia, w tym przypadku nazwą pliku. Kolejnym często używanym parametrem tego programu jest parametr -0 (lub równoważny null). Dzięki niemu jako znak rozgraniczający fragmenty strumienia będzie wykorzystywany znak null. Opcja ta przydatna jest w przypadku nazw plików zawierających spację. Uwaga! Opcja -0 (null) dostępna jest tylko w wersji GNU polecenia xargs.

6. Wyszukiwanie, wyrażenia regularne

Systemy uniksowe oferują kilka przydatnych poleceń służących do wyszukiwania plików, ciągów tekstu, które w połączeniu z przedstawionymi powyżej strumieniami i przekierowaniami oraz z wyrażeniami regularnymi stanowią bardzo potężne narzędzie administratorskie.

6.1. Wyrażenia regularne

Wyrażenia regularne są wzorcami opisującymi, zastępującymi łańcuchy tekstów, zostały one wprowadzone od samego początku istnienia Uniksa przez jednego z jego twórców — Kena Thompsona. Wyrażenia regularne są bardzo efektywnym sposobem pracy z tekstem i zdecydowanie warto je opanować.

Symbol Zastępuje
. dowolny znak
^ dopasuj występujące po operatorze wyrażenie do początku wiersza
$ dopasuj poprzedzające wyrażenie do końca wiersza
\x znaki specjalne, gdzie x to znak specjalny np. \$ zastąpi znak dolara
[lista] zastępuje dowolny znak spośród tych wymienionych na liście, mogą to być przedziały np. [0-9] lub [a-d]
() grupowanie wyrażeń regularnych
? dokładnie jeden element wcześniejszy
a|b dopasuje wyrażenie a lub wyrażenie b
* dopasuj zero lub więcej wyrażeń znaku poprzedzający operator
+ jeden lub więcej elementów poprzedzających operator

6.2. Wyrażenia regularne a znaki globalne

Warto nadmienić że, bash do wersji 3.0 nie miał wbudowanej obsługi wyrażeń regularnych, które to były wykorzystywane przez programy pracujące na strumieniach tekstu np.: sed, awk czy też grep. Za to wbudowana była obsług wyrażeń globalnych i znaków wieloznacznych (ang. wildcards).

Symbol Zastępuje
* dowolny ciąg znaków
? dokładnie jeden znak
[lista] zastępuje dowolny znak spośród tych wymienionych na liście, mogą to być przedziały np. [0-9] lub [a-d]
[^lista] wybrane zostaną znaki, które nie są na liście
{} grupuje wyrażenie globalne

Wyrażenia regularne pozwalają wyszukać dany łańcuch w strumieniu tekstu, podczas gdy wyrażenia globalne zastępują fragmenty tekstu. W poniższym, bardzo prostym przykładzie usunięto wszystkie plik rozpoczynające się na literę "a".

adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls
aa  abc        nowy.txt       przykład.txt
ab  error.txt  polecenie.txt  wszystko_o_konsoli.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ rm a*
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls
error.txt  nowy.txt  polecenie.txt  przykład.txt  wszystko_o_konsoli.txt

W tym natomiast usunięto wszystkie które nie mają jako pierwszej litery z zakresu b do z i dalsza ich nazwa to dowolny ciąg znaków.
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls
aa  abc        nowy.txt       przykład.txt
ab  error.txt  polecenie.txt  wszystko_o_konsoli.txt
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ rm [^b-z]*
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ ls
error.txt  nowy.txt  polecenie.txt  przykład.txt  wszystko_o_konsoli.txt

6.3. grep

grep to powszechnie wykorzystywany program do wyszukiwania w strumieniu wejścia ciągów tekstowych, pasujących do podanego wyrażenia regularnego. Występuje on w każdym systemie uniksowym a jego autorem jest Ken Thompson.
grep ma kilka przydatnych parametrów:

  • -c — wyświetla tylko liczbę znalezionych linii,
  • -n — wyświetlany jest numer linii w pliku, w którym znaleziono dany ciąg znaków,
  • -w — wyszukuje tylko całe słowa,
  • -x — wyszukuje tylko całe linie.
adam@laptop:~/Dokumenty/jakilinux.org/przykłady$ dmesg | grep Mouse
[   15.436000] input: USB-PS/2 Optical Mouse as /class/input/input2
[   15.436000] input: USB HID v1.10 Mouse [USB-PS/2 Optical Mouse] on usb-0000:00:1d.0-2

W powyższym przykładzie wyjście polecenia dmesg (wyświetlającego informacje dziennika zdarzeń jądra systemu) przekierowałem za pomocą potoku (operator |) do polecenia grep, gdzie jako wyrażenia regularnego użyłem słowa "Mouse" (wielkość liter ma znaczenie). Polecenie przefiltrowało wejście i wyświetliło jedynie te linie, które zawierają słowo "Mouse".
Do kolejnych przykładów załóżmy, że mamy plik tekstowy, wyrażenia.txt o zawartości:
1. owoc
2. rower
3. dom
4. auto
5. płyta
6. ananas

Tak więc:
grep ^[1-6]..a wyrażenia.txt 
4. auto
6. ananas

Powyższe wyrażenie wyszuka wszystkie łańcuchy, które zaczynają się od liczb z przedziału od 1 do 6, dalej zawierają dwa dowolne znaki (w naszym przypadku kropkę i spację), dalej zawierają literę "a", za nią dowolny już ciąg znaków.
Wyrażenie poniżej wyświetli każdą linię kończącą się na literę "a".
grep a$ wyrażenia.txt 
5. płyta
grep a.*a  wyrażenia.txt 
6. ananas

Powyższe wyrażenie wyszuka dowolny ciąg zaczynający się na a, dalej zawierający dowolny ciąg znaków, i kończący się na a. W tym przypadku warto zwrócić uwagę na zapis ".*". Jak pamiętamy, znak * w wyrażeniach regularnych zwróci zero lub więcej znaków poprzedzających ten operator, natomiast operator . oznacza dowolny znak. Ujmując to prościej, wyszukujemy w ten sposób zero lub więcej wystąpień dowolnego znaku.
 grep "\(1\|4\)" wyrażenia.txt 
1. owoc
4. auto

Przedstawione powyżej wyrażenie, jest i tyle ciekawe, że użyto w nim znaków, które bash traktuje jako znaki specjalne. Aby to ominąć, postawiłem przed nimi znak \, a całość zamknąłem w cudzysłów, aby uniknąć interpretowania przez bash tego wyrażenia (zrobi to grep).
Tematyka wyrażeń regularnych jest bardzo rozbudowana, dlatego zachęcam do samodzielnego eksperymentowania i ćwiczeń.

6.4. find

Polecenie find przeszukuje drzewo katalogów w poszukiwaniu plików lub katalogów o podanej nazwie lub jej części, lub o podanych kryteriach takich jak: rozmiar, typ, właściciel plików, data utworzenia lub data ostatniej modyfikacji. Najprostsze wywołanie programu find może wyglądać następująco:

adam@laptop:~$ find . -name linux
./Downloads/Firefox/vmware-server-distrib/lib/perl5/site_perl/5.005/i386-linux/linux
./Downloads/Firefox/tp_smapi-0.31/include/linux

Składnia tego polecenia jest następująca: find katalogi_startowe kryterium wyszukiwania i operacje, które należy wykonać na wyszukanych elementach. W powyższym przykładzie katalogiem startowym jest katalog bieżący, jak już wcześniej wspominałem każdy katalog zawiera dowiązanie do siebie samego reprezentowane przez kropkę, oraz kryterium wyszukiwania — wszystkie pliki i katalogi zwierające frazę "linux". Wyszukiwanie rozpoczyna się od katalogu startowego i postępuje w dół drzewa katalogów, tzn. najpierw katalog bieżący, a potem jego podkatalogi, oczywiście o ile ma się prawo do ich odczytu. W programie find można (i warto a wręcz należy) używać znaków globalnych przedstawionych wcześniej.
find umożliwia wyszukiwanie według typu.
adam@laptop:~$ find . -type d

Powyższy przykład wyszuka wszystkie katalogu znajdujące się w bieżącej lokalizacji. Kryteria oczywiście można łączyć.
adam@laptop:~$ find . -type d -name Dokumenty
./Dokumenty
./Dokumenty/jakilinux.org/Dokumenty

Powyższe wywołanie znajdzie wszystkie katalogi w bieżącej lokalizacji zawierające w swej nazwie zwrot "Dokumenty". Możliwe typy plików przedstawia poniższa tabela.
Parametr Rodzaj pliku
b urządzenie blokowe
c urządzenie znakowe
d katalog
f zwykły plik
l dowiązanie symboliczne
s gniazdo (ang. socket)

find wywołany z parametrem -size wartość, wyszuka pliki o wielkości podanej w parametrze wartość, jeżeli do wartości dodamy znak + (np. -size +wartość), program wyszuka pliki większe od podanej wartości. Jeżeli dodamy znak - (np. -size -wartość), wyszukane zostaną pliki mniejsze od podanej wartości. Domyślna wartość to 512 bitowe bloki, pozostałe wartości to:

  • c — bajty,
  • k — kilobajty,
  • M — megabajty,
  • G — gigabajty.

W poniższym przykładzie zostaną wyszukane wszystkie pliki o rozmiarze większym niż 100 MB ale mniejszym niż 200 MB.

adam@laptop:~$ find . -size +100M -size -200M
./plan9_070107.zip

Pozostałe kryteria wyszukiwania przedstawia poniższa tabela.
-atime n Ostatni dostęp miał miejsce n dni temu
-mtime n Plik został zmodyfikowany n dni temu
-newer plik Wyszukiwany plik został zmodyfikowany wcześniej niż podany plik
-links n Plik zawiera dokładnie n twardych dowiązań
-perm p Plik ma uprawnienia, gdzie p to liczbowy tryb dostępu
-user użytkownik Właścicielem pliku jest użytkownik
-group grupa Właścicielem pliku jest grupa
-empty Puste pliki

Opcje liczbowe można poprzedzać znakami + i -, które oznaczają odpowiednio "więcej niż" oraz "mniej niż", podobnie jak miało to miejsce w kryterium time opisanym wcześniej.

Jak już wcześniej wspominałem, polecenie find może wykonać określone operacje na plikach, które znajdzie. Domyślną operacją jest -print, która wypisuje nazwy łacznie z adresami plików. W niektórych powłokach należy dodawać tę opcję za każdym razem.
Kolejna możliwa akcja to -ls, która wypisuje informacje o plikach w ten sam sposób, co polecenie ls uruchomione z parametrami -lids. Ostatnia możliwość to uruchomienie z parametrem -exec i wykonanie dowolnego polecenia na znalezionych plikach.

adam@laptop:~$ find . -size +100M -size -150M -ls
2485508 115744 -rw-r--r--   1 adam     adam     118398976 maj  2 22:44 ./plan9/plan9_compressed.img
 find . -size +110M -size -150M -exec cp {} /home/adam/pliki/ \;

Pierwszy z powyższych przykładów, jak widać, wypisze szczegółowe dane wyszukanych plików. Drugi jest ciekawszy i wymaga dokładniejszej analizy. find wykona na plikach operację podaną wraz z parametrem. W tym przypadku, wszystkie pliki większe niż 110 MB i mniejsze niż 150 MB zostaną skopiowane do katalogu pliki, podwójny nawias klamrowy {} oznacza, że operacja ma być wykonana na każdym pliku a \ przed ; chroni przed błędną interpretacją polecenia przez powłokę.
find ma jeszcze inne ciekawe opcje: -ok — działa podobnie jak -exec z tą różnicą, że przed każdą operacją użytkownik proszony jest o potwierdzenie działania, -prune powoduje, że find nie wchodzi do żadnego z napotkanych katalogów.

Składnia find umożliwia tworzenie złożonych wyrażeń, łączenia kryteriów. Domyślnie kryteria łączone są za pomocą logicznej koniunkcji (AND): (-a). Wszystkie kryteria muszą być spełnione, aby plik został uznany za zgodny z kryteriami. Operator łączenia alternatywy logicznej (OR): -o, natomiast operator negacji to: \! Istnieje możliwość wykorzystania nawiasów w celu grupowania kryteriów \( \).
Ważnym parametrem polecenia find jest parametr -print0, w przypadku jego użycia, nazwy znalezionych plików nie są rozdzielane znakiem nowej linii a znakiem null. Rozpatrzmy przykład poniżej, w którym użyjemy dwóch plików: raport czerwiec.txt i raportczerwiec.txt.

adam@laptop:~$ find . -name "raport*" | xargs rm 
rm: nie można usunąć `./raport': No such file or directory
rm: nie można usunąć `czerwiec.txt': No such file or directory

Poleceniu rm nie udało sie usunąć pliku raport czerwiec.txt, ponieważ zawiera on spację w nazwie i jego nazwa została w tym miejscu rozdzielona.
find . -name "raport*" -print0 | xargs -0 rm

Polecenie print otrzymało opcję -print0, natomiast polecenie xargs opcję -0, dzięki czemu bez problemu usunięty został plik zawierający spację. Uwaga! Opcja -print0 dostępna jest tylko w wersji GNU polecenia find.

7. Zmienne środowiskowe

Jak podaje Wikipedia, zmienne środowiskowe to zbiór dynamicznych wartości, wpływających na sposób w jaki działać będą uruchomione procesy (programy). Zmienne systemowe występują w każdym systemie operacyjnym Unix, Unix-like oraz MS DOS i Windows. Oczywiście różne systemy korzystać będą z różnych zbiorów zmiennych, jednak najczęściej większość zmiennych będzie wspólna.
Początkujący użytkownicy bardzo często boją się korzystać ze zmiennych systemowych w obawie przed uszkodzeniem systemu, traktując je jako rzecz nie do ogarnięcia. Oczywiście jest to podejście jak najbardziej błędne. Bash pozwala również na tworzenie tzw. zmiennych powłoki, które działają na zasadzie identycznej jak zmienne środowiskowe przy czym ich zasięg dotyczy tylko powłoki, w której zostały utworzone.

7.1. Niektóre zmienne środowiskowe

Zmienna Opis
PATH Zmienna zawiera oddzieloną dwukropkami listę katalogów w której, powłoka będzie szukać programu którego nazwę do wykonania wprowadził użytkownik, jeżeli taki program nie zostanie znaleziony, powłoka wyświetli komunikat "polecenie nie odnalezione"
EDITOR Domyślny edytor tekstu, zmienna wykorzystywana przez niektóre programy np. przez klienta poczty mutt. W jego przypadku emaile edytowane są w programie określonym przez tę zmienną
SHELL Powłoka wykorzystywana przez użytkownika
USER Nazwa użytkowanika
SHLVL Liczba uruchomionych powłok
TERM Domyślnie uruchamiany emulator terminala
HOME Domyślna ścieżka do katalogu domowego użytkownika
UID Unikalny liczbowy identyfikator zalogowanego użytkownika
$LANG, $LC_ALL Zmienne przechowujące ustawienia językowe (locale)

7.2. Wyświetlanie wartości zmiennej

Aby wyświetlić wartość jaką ma dana zmienna, używamy znanego już polecenia echo $zmienna.

adam@laptop:~$ echo $USER $UID $SHELL $HOME
adam 1000 /bin/bash /home/adam

Aby wyświetlić wszystkie używane zmienne, można użyć polecenia env. W poniższym przykładzie pokazany jest tylko fragment bardzo długiego wyjścia. Alternatywnie można użyć wbudowanego w basha polecenia set.
adam@laptop:~$ env
SSH_AGENT_PID=5605
TERM=xterm
DESKTOP_STARTUP_ID=
SHELL=/bin/bash
GTK_RC_FILES=/etc/gtk/gtkrc:/home/adam/.gtkrc-1.2-gnome2
WINDOWID=58896938
GTK_MODULES=gail:atk-bridge
USER=adam
USERNAME=adam
DESKTOP_SESSION=gnome
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
PWD=/home/adam
LANG=pl_PL.UTF-8
GDMSESSION=gnome
HOME=/home/adam
SHLVL=2
LOGNAME=adam

7.3. Tworzenie nowych zmiennych

Nową zmienną tworzy się wpisując jej nazwę i wartość jaką będzie ona miała. Na przykład zmienna=wartość. Zmienne są czułe na wielkość liter, tak więc ZMIENNA nie będzie tym samym co zmienna pisana małymi literami. Zwyczajowo przyjęło się pisać nazwy zmiennych wielkimi literami.

adam@laptop:~$ ZMIENNA=wartość
adam@laptop:~$ echo $ZMIENNA
wartość

Utworzona powyżej zmienna powłoki ma pewną nieprzyjemną cechę, mianowicie dostępna będzie jedynie w powłoce, w której została utworzona, a programy uruchomione z tej powłoki, nie będą miały do niej dostępu. Aby obejść to ograniczenie, należy wyeksportować zmienną za pomocą polecenia export.
adam@laptop:~$ ZMIENNA=wartość
adam@laptop:~$ ZMIENNA2=wartość2
adam@laptop:~$ export $ZMIENNA2
adam@laptop:~$ export ZMIENNA2
adam@laptop:~$ bash #uruchamiam nową powłokę
adam@laptop:~$ echo $ZMIENNA1 $ZMIENNA2
wartość2

W powyższym przykładzie wyeksportowałem tylko jedną zmienną, jej wartość jest dostępna w nowo uruchomionej powłoce.

7.3. Zapamiętywanie wartości zmiennej

Wszystkie nowo utworzone zmienne, zarówno te wyeksportowane jak i niewyeksportowane, będą dostępne tak długo, jak użytkownik będzie zalogowany. Aby zmienna dostępna była po ponownym zalogowaniu się, należy dodać ją do ukrytego pliku .profile. Jeżeli zmienna ma być dostępna dla każdego użytkownika systemu, należy dodać ją do pliku /etc/profile. Oto przykładowa linia z pliku .profile (konfiguracja serwera anoncvs do pobierania plików źródłowych systemu NetBSD).

export CVSROOT=anoncvs@anoncvs.netbsd.org:/cvsroot

7.4. Usuwanie zmiennych

Aby usunąć zmienną, należy użyć polecenia unset.

adam@laptop:~$ ZMIENNA=wartość
adam@laptop:~$ echo $ZMIENNA
wartość
adam@laptop:~$ unset ZMIENNA
adam@laptop:~$ echo $ZMIENNA
Dodaj nową wypowiedź
lub Zaloguj się jako użytkownik serwisu Wikidot.com
(nie będzie opublikowany)
- +
O ile nie zaznaczono inaczej, treść tej strony objęta jest licencją Creative Commons Attribution-NonCommercial 3.0 License