Uwaga: Oryginalna wersja tego artykułu została opublikowana w IBM developerWorks i jest własnością Westtech Information Services. Poniższy dokument jest poprawioną przez zespół GDP wersją oryginalnego tekstu i nie jest już aktualizowany. |
Witamy w "Podstawach Linuksa", pierwszym z czterech materiałów szkoleniowych będących przygotowaniem do egzaminu 101 Linux Professional Institute. W tym wprowadzeniu zostanie przedstawiony bash (standardowa powłoka Linuksa), pokazane zostanie w jaki sposób w pełni wykorzystać standardowe polecenia Linuksa takie jak ls, cp i mv, zostaną wytłumaczone węzły oraz twarde i symboliczne dowiązania i wiele więcej. Zapoznanie się z tym wprowadzeniem zapewni zdobycie solidnych podstaw Linuksa i pozwoli na dalszą naukę podstawowych zadań związanych z administrowaniem Linuksem. Zapoznanie się z całą serią materiałów szkoleniowych (w sumie osiem) zapewni wiedzę potrzebną do tego aby zostać Administratorem Systemu Linux oraz pozwoli przystąpić do pierwszego egzaminu LPIC organizowanego przez Linux Professional Institute.
Niniejsze wprowadzenie (Część 1) jest idealne dla wszystkich początkujących użytkowników Linuksa lub dla tych, którzy chcą odświeżyć lub utrwalić swoją wiedzę na temat podstawowych zadań takich jak kopiowanie i przenoszenie plików, tworzenie dowiązań symbolicznych i twardych oraz korzystania ze standardowych poleceń przetwarzających tekst wraz z potokami i przekierowaniami. Przy okazji można znaleźć tutaj wiele wskazówek, podpowiedzi i trików, co czyni ten materiał praktycznym i rzeczowym nawet dla osób posiadających już spore doświadczenie. Dla początkujacych większość tego materiału będzie czymś zupełnie nowym, a dla doświadczonych użytkowników Linuksa może okazać się idealnym sposobem na doszlifowanie swoich umiejętności.
Osoby, które poznały pierwsze wydanie tego materiału z innych powodów niż przygotowanie do egzaminu LPI nie muszą przerabiać niniejszego wstępu. Ci jednak, którzy planują przystapienie do egzaminu powinni poważnie wziąć pod uwagę przeczytanie tego skorygowanego wstępu.
Daniel Robbins zamieszkujący w Albuquerque, w stanie Nowy Meksyk, jest głównym architektem dystrybucji Gentoo Linux. Zajmuje się także pisaniem artykułów dla strefy Linuksa na IBM Developer Works oraz dla Intel Developer Services. Jest także współautorem kilku książek, wliczając w to Samba Unleashed oraz SUSE Linux Unleashed. Daniel lubi spędzać czas ze swoją żoną Mary oraz ze swoją córeczką Hadassah. Można się z nim skontaktować pisząc na adres poczty elektronicznej drobbins@gentoo.org.
Jeżeli ktoś używał już systemu Linux, pamięta, że po zalogowaniu witany jest znakiem zachęty, który wygląda mniej więcej tak:
Listing 2.1: Znak zachęty |
$ |
Znak zachęty widziany przez konkretnego użytkownika może być całkiem inny. Może zawierać nazwę stacji użytkownika, nazwę katalogu bieżącego albo i jedno i drugie. Niezależnie jednak od tego jak wygląda znak zachęty można być pewnym jednej rzeczy. Tego, że program, który wyświetlił znak zachęty nazywany jest "powłoką" i jest bardzo prawdopodobne, że jest to powłoka zwana bash.
W celu sprawdzenia czy korzystamy z powłoki bash należy wpisać:
Listing 2.2: Zmienna SHELL |
$ echo $SHELL
/bin/bash
|
Jeżeli wynikiem powyższego polecenia będzie informacja o błędzie albo będzie wynikiem różniącym się od pokazanego powyżej, może to oznaczać, że korzystamy z powłoki innej niż bash. W takim przypadku większość tego wprowadzenia powinna nadal być przydatna, nie mniej jednak, przez wzgląd na przygotowanie do egzaminu 101, pomocnym byłoby przejście na powłokę bash.
Bash, którego nazwa jest skrótem od "Bourne-again shell", jest standardową powłoką większości systemów Linuks. Zadaniem powłoki jest słuchanie poleceń użytkownika, tak aby mógł on komunikować się ze swoim systemem Linuks. Po zakończeniu wprowadzania poleceń można zakończyć pracę w powłoce poprzez wylogowanie i wtedy wróci się do znaku zachęty logowania.
A tak przy okazji, to wylogować można się poprzez naciśnięcie klawiszy control-D.
Startowanie ze znakiem zachęty basha nie jest najbardziej ekscytującą rzeczą na świecie. Zacznijmy więc korzystać z powłoki bash w celu poruszania się po naszym systemie plików. W linii poleceń wpisujemy (bez $):
Listing 2.3: Zmiana katalogu |
$ cd /
|
Właśnie powiedzieliśmy powłoce, że chcemy pracować w katalogu /, nazywanym również katalogiem głównym. Wszystkie katalogi w systemie plików tworzą drzewo a / jest wierzchołkiem tego drzewa albo jego korzeniem. Polecenie cd zmienia katalog, w którym aktualnie pracujemy zwanym także katalogiem bieżącym.
Aby zobaczyć jaki katalog jest katalogiem bieżącym, należy wpisać:
Listing 2.4: Wyświetlanie nazwy katalogu bieżącego |
$ pwd
/
|
W powyższym przykładzie argument / do polecenia cd nazywany jest ścieżką. Informuje on polecenie cd o tym gdzie chcemy się dostać. Dokładnie rzecz ujmując argument / jest ścieżką absolutną, co oznacza, że podaje lokalizację względem katalogu głównego.
Oto kilka przykładów ścieżek absolutnych:
Listing 2.5: Przykłady ścieżek absolutnych |
/dev /usr /usr/bin /usr/local/bin |
Jak widać, jedną wspólną cechą wszystkich ścieżek absolutnych jest to, że zaczynają się od /. Podając ścieżkę /usr/local/bin wskazujemy poleceniu cd, że ma najpierw przejść do katalogu /, z niego przejśc do katalogu usr i dalej do katalogu local i bin. Ścieżki absolutne zawsze zaczynają się od /.
Inny rodzaj ścieżek nazywany jest ścieżkami względnymi. Bash, cd i inne polecenia zawsze interpretują te ścieżki względem katalogu bieżącego. Ścieżki względne nigdy nie zaczynają się od /. Czyli, gdybyśmy byli w katalogu /usr:
Listing 2.6: Zmiana katalogu przy użyciu ścieżek względnych |
$ cd /usr
|
Wtedy, aby przejść do katalogu /usr/local/bin moglibysmy użyć ścieżki względnej:
Listing 2.7: Zmiana katalogu przy użyciu ścieżek względnych |
$ cd local/bin $ pwd /usr/local/bin |
Ścieżki względne mogą również zawierać jeden lub więcej katalogów .. . Katalog .. jest katalogiem specjalnym, który wskazuje na katalog nadrzędny. Kontynuując powyższy przykład:
Listing 2.8: Korzystanie z notacji 'katalog nadrzędny' |
$ pwd /usr/local/bin $ cd .. $ pwd /usr/local |
Jak widać, w tej chwili katalogiem bieżącym jest /usr/local. "Cofnęliśmy się" o jeden katalog względem katalogu bieżącego, w którym wcześniej byliśmy.
Dodatkowo symbol .. może zostać dodany do ścieżki względnej, co pozwoli nam przejść do katalogu równoległego do tego, w którym się właśnie znajdujemy, np:
Listing 2.9: Stosowanie notacji katalogu nadrzędnego w ściezkach względnych |
$ pwd /usr/local $ cd ../share $ pwd /usr/share |
Ścieżki względne mogą być dość skomplikowane. Poniżej przedstawiamy kilka przykładów bez pokazywania jaki jest katalog wynikowy. Spróbujmy zastanowić się nad tym w jakim katalogu się znajdziemy po wykonaniu poniższych poleceń:
Listing 2.10: Przykłady ścieżek absolutnych |
$ cd /bin $ cd ../usr/share/zoneinfo $ cd /usr/X11R6/bin $ cd ../lib/X11 $ cd /usr/bin $ cd ../bin/../bin |
Teraz wykonajmy te polecenia i sprawdźmy czy dobrze odgadliśmy. :)
Przed zakończeniem omawiania polecenia cd należy jeszcze wspomnieć o kilku rzeczach. Po pierwsze istnieje jeszcze jeden katalog specjalny o nazwie ., co oznacza "katalog bieżący". Katalog ten raczej nie jest używany z poleceniem cd, niemniej jednak często jest używany do uruchamiania programów znajdujących się w katalogu bieżącym, tak jak to pokazano poniżej:
Listing 2.11: Uruchamianie programu z katalogu bieżącego |
$ ./myprog
|
W powyższym przykładzie zostanie uruchomiony program myprog znajdujący się w katalogu bieżącym.
Jeśli chcielibyśmy przejść do naszego katalogu macierzystego moglibyśmy wpisać:
Listing 2.12: Przejście do katalogu macierzystego |
$ cd
|
Polecenie cd wpisane bez żadnych argumentów przeniesie nas do naszego katalogu macierzystego czyli katalogu /root dla administratora lub standardowo do /home/nazwa_użytkownika dla zwykłego użytkownika. Jednak co robić gdybyśmy chcieli wskazać plik w naszym katalogu macierzystym? Powiedzmy, że chcielibyśmy przekazać argument dla programu myprog. Jeżeli plik ten leży w naszym katalogu macierzystym wtedy moglibyśmy wpisać:
Listing 2.13: Uruchomienie programu z katalogu bieżącego |
$ ./myprog /home/drobbins/myfile.txt
|
Stosowanie ścieżki absolutnej nie jest najwygodniejsze. Na szczęście możemy zastosować znak ~ (tylda), aby osiągnąć ten sam efekt.
Listing 2.14: Używanie notacji katalogu macierzystego |
$ ./myprog ~/myfile.txt
|
Katalogi macierzyste innych użytkowników
Bash rozwinie znak ~ jako wskazanie do naszego katalogu macierzystego, ale możemy też za pomocą tego znaku wskazać na katalog macierzysty innych użytkowników. Gdybyśmy przykładowo chcieli wskazać na plik fredsfile.txt znajdujący się w katalogu macierzystym Freda, moglibyśmy wpisać:
Listing 2.15: Przykładowe zastosowanie notacji katalogu macierzystego |
$ ./myprog ~fred/fredsfile.txt
|
3. Korzystanie z poleceń Linuksa
Omówimy teraz polecenie ls. Prawdopodobnie każdy już spotkał się z tym poleceniem i wie, że wpisanie go powoduje wyświetlenie listy z zawartością katalogu bieżącego:
Listing 3.1: Wyświetlanie listy plików |
$ cd /usr $ ls X11R6 doc i686-pc-linux-gnu lib man sbin ssl bin gentoo-x86 include libexec portage share tmp distfiles i686-linux info local portage.old src |
Dodając opcję -a możemy zobaczyć wszystkie pliki w katalogu, razem z plikami ukrytymi, czyli tymi zaczynającymi się od .. Jak widać w poniższym przykładzie polecenie ls -a pokazuje również specjalne katalogi . oraz ..:
Listing 3.2: Wyświetlanie listy plików, łącznie z plikami ukrytymi |
$ ls -a
. bin gentoo-x86 include libexec portage share tmp
.. distfiles i686-linux info local portage.old src
X11R6 doc i686-pc-linux-gnu lib man sbin ssl
|
Wyświetlanie szczegółowej listy
Przy pomocy polecenia ls można wskazać na jeden lub więcej plików bądź katalogów. Jeżeli zostanie wskazany plik, wtedy polecenie ls wyświetli tylko ten plik. Jeżeli zostanie wskazany katalog, ls wyświetli zawartość tego katalogu. Opcja -l jest bardzo przydatna gdy dodatkowo chcemy zobaczyć informacje o prawach dostępu, własności, dacie modyfikacji czy też o rozmiarze wyświetlonych elementów.
W poniższym przykładzie korzystamy z opcji -l w celu wyświetlenia pełnej informacji o zawartości katalogu /usr.
Listing 3.3: Wyświetlanie listy plików z pełną informacją |
$ ls -l /usr
drwxr-xr-x 7 root root 168 Nov 24 14:02 X11R6
drwxr-xr-x 2 root root 14576 Dec 27 08:56 bin
drwxr-xr-x 2 root root 8856 Dec 26 12:47 distfiles
lrwxrwxrwx 1 root root 9 Dec 22 20:57 doc -> share/doc
drwxr-xr-x 62 root root 1856 Dec 27 15:54 gentoo-x86
drwxr-xr-x 4 root root 152 Dec 12 23:10 i686-linux
drwxr-xr-x 4 root root 96 Nov 24 13:17 i686-pc-linux-gnu
drwxr-xr-x 54 root root 5992 Dec 24 22:30 include
lrwxrwxrwx 1 root root 10 Dec 22 20:57 info -> share/info
drwxr-xr-x 28 root root 13552 Dec 26 00:31 lib
drwxr-xr-x 3 root root 72 Nov 25 00:34 libexec
drwxr-xr-x 8 root root 240 Dec 22 20:57 local
lrwxrwxrwx 1 root root 9 Dec 22 20:57 man -> share/man
lrwxrwxrwx 1 root root 11 Dec 8 07:59 portage -> gentoo-x86/
drwxr-xr-x 60 root root 1864 Dec 8 07:55 portage.old
drwxr-xr-x 3 root root 3096 Dec 22 20:57 sbin
drwxr-xr-x 46 root root 1144 Dec 24 15:32 share
drwxr-xr-x 8 root root 328 Dec 26 00:07 src
drwxr-xr-x 6 root root 176 Nov 24 14:25 ssl
lrwxrwxrwx 1 root root 10 Dec 22 20:57 tmp -> ../var/tmp
|
Pierwsza kolumna pokazuje informacje o prawach dostępu do każego elementu na liście. Za chwilę objaśnimy jak interpretować te informacje. Następna kolumna to informacja o ilości dowiązań do każdego z elementów na liście. W tej chwili tylko o tym wspominamy, lecz później wrócimy do tej danej. Trzecia i czwarta kolumna pokazuje odpowiednio właściciela i grupę. Piąta kolumna to informacja o rozmiarze obiektu. Szósta kolumna podaje czas ostatniej modyfikacji inaczej zwany "mtime". Ostatnia kolumna to nazwa elementu. Jeżeli plik jest dowiązaniem symbolicznym to na końcu będzie widać strzałkę -> i ścieżkę, na którą dowiązanie wskazuje.
Czasami chcemy wyświetlić informacje o samym katalogu, a nie o jego zawartości. W takiej sytuacji należy podać opcję -d, dzięki której polecenie ls wyświetli tylko katalogi, a nie ich zawartość.
Listing 3.4: Wydruk katalogów |
$ ls -dl /usr /usr/bin /usr/X11R6/bin ../share
drwxr-xr-x 4 root root 96 Dec 18 18:17 ../share
drwxr-xr-x 17 root root 576 Dec 24 09:03 /usr
drwxr-xr-x 2 root root 3192 Dec 26 12:52 /usr/X11R6/bin
drwxr-xr-x 2 root root 14576 Dec 27 08:56 /usr/bin
|
Listowanie rekursywne oraz węzły
Jak widać, korzystając z opcji -d jesteśmy w stanie wyświetlić tylko katalogi, stosując jednak opcję -R robimy coś dokładnie odwrotnego: nie dość, że wyświetlamy zawartość katalogu, to jeszcze dodatkowo rekurencyjnie wyświetlamy pliki i zawartość katalogów znajdujących się w tym katalogu! Nie załączamy żadnego przykładu takiego wydruku (ponieważ zazwyczaj taki wydruk jest bardzo długi), ale można samemu spróbować wykonać polecenie ls -R i ls -Rl, aby sprawdzić jak wygląda efekt tych poleceń.
Na koniec powiemy o opcji -i, która jest wykorzystywana do wyświetlania numeru i-węzła obiektu:
Listing 3.5: Wyświetlanie i-węzła |
$ ls -i /usr
1409 X11R6 314258 i686-linux 43090 libexec 13394 sbin
1417 bin 1513 i686-pc-linux-gnu 5120 local 13408 share
8316 distfiles 1517 include 776 man 23779 src
43 doc 1386 info 93892 portage 36737 ssl
70744 gentoo-x86 1585 lib 5132 portage.old 784 tmp
|
Do każdego obiektu w systemie plików przypisany jest unikatowy indeks zwany numerem i-węzła. Może się to wydawać banalne, nie mniej jednak zrozumienie i-węzłów jest kluczowym dla zrozumienia wielu operacji na systemie plików. Rozważając na przykład dowiązania . oraz .., które występują w każdym katalogu. Żeby zrozumieć czym jest katalog .. spójrzmy najpierw na numer i-węzła katalogu /usr/local:
Listing 3.6: Wyświetlanie numeru i-węzła katalogu |
$ ls -id /usr/local
5120 /usr/local
|
Katalog /usr/local posiada numer i-węzła 5120. Sprawdźmy teraz jaki jest numer i-węzła katalogu /usr/local/bin/..:
Listing 3.7: Wyświetlanie numeru i-węzła katalogu |
$ ls -id /usr/local/bin/..
5120 /usr/local/bin/..
|
Jak widać katalog /usr/local/bin/.. ma taki sam numer i-węzła jak katalog /usr/local! Oto jak dochodzimy do ładu z tą szokującą rewelacją. Wcześniej uważaliśmy, że /usr/local to katalog. Teraz odkryliśmy, że tak na prawdę katalogiem jest i-węzeł o numerze 5120 oraz, że dwa wpisy katalogów (zwanych dowiązaniami) wskazują na właśnie ten i-węzeł. Zarówno /usr/local jak i /usr/local/bin/.. są dowiązaniami do i-węzła 5120. I-węzeł 5120 istnieje fizycznie tylko w jednym miescu na dysku, a wiele elementów na niego wskazuje. Fizycznym wpisem na dysku jest i-węzeł 5120.
Aby dowiedzieć się ile tak naprawdę elementów wskazuje na i-węzeł 5120, należy wydać polecenie ls -ld:
Listing 3.8: Wyświetlanie ilości dowiązań do i-węzłą |
$ ls -dl /usr/local
drwxr-xr-x 8 root root 240 Dec 22 20:57 /usr/local
|
Patrząc na drugą kolumnę od lewej zobaczymy, że katalog /usr/local (numer i-węzła 5120) jest wskazywany osiem razy. Oto ściezki, które wskazują na ten i-węzeł w moim systemie plików:
Listing 3.9: Dowiązania do i-węzła |
/usr/local /usr/local/. /usr/local/bin/.. /usr/local/games/.. /usr/local/lib/.. /usr/local/sbin/.. /usr/local/share/.. /usr/local/src/.. |
Omówimy teraz polecenie mkdir, które służy do tworzenia nowych katalogów. Poniższy przykład tworzy trzy nowe katalogi, tic, tac i toe, wszystkie w katalogu /tmp:
Listing 3.10: Tworzenie katalogów |
$ cd /tmp $ mkdir tic tac toe |
Domyślnie, polecenie mkdir nie tworzy katalogów nadrzędnych; cała ściezka katalogów, w której chcemy utworzyć nowy katalog musi istnieć. Czyli, aby utworzyć katalogi won/der/ful, nalezy wydać trzy osobne polecenia mkdir:
Listing 3.11: Tworzenie katalogów nadrzędnych |
$ mkdir won/der/ful mkdir: cannot create directory `won/der/ful': No such file or directory $ mkdir won $ mkdir won/der $ mkdir won/der/ful |
Polecenie mkdir posiada jednak bardzo przydatną opcję -p, która tworzy wszystkie nieistniejące wcześniej katalogi nadrzędne, tak jak to widać poniżej:
Listing 3.12: Tworzenie katalogów nadrzędnych za pomocą jednego polecenia |
$ mkdir -p easy/as/pie
|
Jak widać, jest to całkiem proste. Więcej o poleceniu mkdir można dowiedzieć się wpisując man mkdir i czytając dokumentację systemową. Działa to prawie dla wszystkich polceń tutaj opisywanych (np. man ls), oprócz polecenia cd, które jest wbudowanym poleceniem powłoki bash.
Omówimy teraz polecenia cp oraz mv, które służą do kopiowania, zmiany nazwy oraz przenoszenia plików i katalogów. Aby rozpocząć omawianie tych poleceń najpierw skorzystamy z polecenia touch w celu utworzenia pliku w katalogu /tmp:
Listing 3.13: Tworzenie pliku |
$ cd /tmp $ touch copyme |
Jeżeli plik istnieje, to polecenie touch aktualizuje parametr "mtime" pliku (przypomnijmy sobie szóstą kolumnę w wyniku polecenia ls -l). Jeżeli plik nie istnieje, to zostanie utworzony nowy, pusty plik. Teraz powinniśmy mieć plik /tmp/copyme o zerowym rozmiarze.
Gdy już mamy plik, dodajmy do niego trochę danych. Można to zrobić za pomocą polecenia echo, które przyjmowane argumenty wysyła na standardowe wyjście. Najpierw samo polecenie echo:
Listing 3.14: Tworzenie pliku za pomocą polecenia 'echo' |
$ echo "firstfile"
firstfile
|
Teraz to samo polecenie echo, ale z przekierowaniem wyjścia:
Listing 3.15: Korzstanie z przekierowania wyjścia |
$ echo "firstfile" > copyme
|
Znak większości mówi powłoce aby wyjście polecenia echo zapisać do pliku o nazwie copyme. Jeżeli plik ten nie istnieje to zostanie utworzony, a jeżeli istnieje to zostanie nadpisany. Z pomocą polenia ls -l można sprawdzić, że plik copyme ma rozmiar 10 bajtów ponieważ zawiera słowo firstfile oraz znak nowej linii:
Listing 3.16: Drukowanie informacji o pliku |
$ ls -l copyme
-rw-r--r-- 1 root root 10 Dec 28 14:13 copyme
|
W celu wyświetlenia na terminalu zawartości pliku należy skorzystać z polecenia cat:
Listing 3.17: Wyświetlanie zawartości pliku |
$ cat copyme
firstfile
|
Teraz możemy użyć podstawowego polecenia cp w celu utworzenia pliku copiedme z oryginalnego pliku copyme:
Listing 3.18: Kopiowanie pliku |
$ cp copyme copiedme
|
Gdy się im przyjrzymy, zobaczymy, że faktycznie są to dwa osobne pliki; posiadają inne numery i-węzła:
Listing 3.19: Sprawdzanie numeru i-węzła |
$ ls -i copyme copiedme
648284 copiedme 650704 copyme
|
Teraz użyjemy polecenia mv, aby zmienić nazwę pliku "copiedme" na "movedme". Numer i-węzła pozostanie taki sam, ale zmieni się nazwa pliku wskazującego na ten numer i-węzła.
Listing 3.20: Zmiana nazwy pliku |
$ mv copiedme movedme $ ls -i movedme 648284 movedme |
Numer i-węzła pliku pozostanie taki sam tak długo, jak długo pliki będą znajdowały się w obrębie tego samego systemu plików. Systemy plików zostaną omówione dokładniej w Części 3 niniejszego wprowadzenia.
Jeśli już mówimy o poleceniu mv to powiemy też o innym sposobie wykorzystania tego polecenia. Polecenie mv oprócz tego, że pozwala na zmianę nazwy pliku, to służy również do przenoszenia jednego lub większej ilości plików do innej lokalizacji w hierarchi katalogów. Przykładowo, aby przenieść /var/tmp/myfile.txt do katalogu /home/drobbins (tak się składa, że jest to mój kataog macierzysty), mogę wpisać:
Listing 3.21: Przenoszenie pliku |
$ mv /var/tmp/myfile.txt /home/drobbins
|
Po wpisaniu tego polecenia plik myfile.txt zostanie przeniesiony do /home/drobbins/myfile.txt. Jeżeli /home/drobbins jest w obrębie innego systemu plików niż /var/tmp, wtedy polecenie mv zadba o skopiowanie pliku myfile.txt na nowy system plików oraz skasowanie go z poprzedniego systemu plików. Jak można się domyślać, po skopiowaniu pliku myfile.txt na inny system plików plik myfile.txt w nowej lokalizacji będzie posiadał nowy numer i-węzła. Dzieje się tak dlatego, ze każdy system plików posiada własny, niezależny zakres numerów i-węzłów.
Polecenia mv można używać również dla przeniesienia wielu plików do jednego miejsca w konkretnym katalogu. Przykładowo, w celu przeniesienia pliku myfile1.txt i myarticle3.txt do /home/drobbins mogę wpisać:
Listing 3.22: Przenoszenie wielu plików |
$ mv /var/tmp/myfile1.txt /var/tmp/myarticle3.txt /home/drobbins
|
4. Tworzenie dowiązań i usuwanie plików
Używaliśmy już pojęcia "dowiązanie" gdy mówilismy o relacji między katalogami (ich "nazwami"), a i-węzłami (numer indeksu w systemie plików, który zazwyczaj możemy zignorować). W Linuksie istnieją dwa rodzaje dowiązań. Taki rodzaj dowiązanie o jakim mówiliśmy wcześniej nazywany jest dowiązaniem twardym. Konkretny i-węzeł może posiadać dowolną ilość dowiązań twardych i pozostanie on na systemie plików dopóki nie znikną wszystkie dowiązania twarde do tego i-węzła. Jeżeli zniknie ostatnie dowiązanie twarde do tego i-węzła i nie jest on otwarty przez jakiś program to Linux automatycznie go skasuje. Nowe twarde dowiązania można stworzyć za pomocą polecenia ln:
Listing 4.1: Tworzenie dowiązań do plików |
$ cd /tmp $ touch firstlink $ ln firstlink secondlink $ ls -i firstlink secondlink 15782 firstlink 15782 secondlink |
Jak widać, dowiązania twarde działają na poziomie i-węzłów, aby wskazywać na określony plik. W Linuksie dowiązania twarde posiadają kilka ograniczeń. Po pierwsze możemy stworzyć dowiązania twarde tylko do plików, a nie do katalogów. Tak właśnie jest,że pomimo tego, że . oraz .. są systemowo utworzonymi dowiązaniami twardymi do katalogów to żaden użytkownik (nawet administrator) nie może sam utworzyć dowiązania twardego do katalogu. Drugim ograniczeniem dowiązań twardych jest to, że nie mogą one przechodzić pomiędzy różnymi systemami plików. Oznacza to, że nie można utworzyć dowiązania twardego /usr/bin/bash do /bin/bash jeżeli katalogi / i /usr znajdują się na innych systemach plików.
W praktyce częściej stosowane są dowiązania symboliczne niż dowiązania twarde. Dowiązania symboliczne są to specjalne pliki, które wskazują na inny plik za pomocą jego nazwy a nie za pomocą i-węzła. Dowiązania symboliczne nie uniemożliwiają skasowania pliku, na który wskazują; jeżeli plik, na który wskazują zostanie usunięty wtedy dowiązanie symboliczne będzie po prostu bezużyteczne, błędne.
Dowiązanie symboliczne tworzone jest poprzez dodanie opcji -s do polecenia ln.
Listing 4.2: Przeglądanie dowiązań symbolicznych |
$ ln -s secondlink thirdlink $ ls -l firstlink secondlink thirdlink -rw-rw-r-- 2 agriffis agriffis 0 Dec 31 19:08 firstlink -rw-rw-r-- 2 agriffis agriffis 0 Dec 31 19:08 secondlink lrwxrwxrwx 1 agriffis agriffis 10 Dec 31 19:39 thirdlink -> secondlink |
W wydruku jaki otrzymujemy po wykonaniu polecenia ls -l dowiązania symbolincze można odróżnić na trzy sposoby. Po pierwsze należy zauważyć, że pierwsza kolumna zawiera literę l co oznacza dowiązanie symboliczne. Po drugie, rozmiar dowiązania symbolicznego jest dokładnie taki ile jest znaków w nazwie obiektu docelowego (w tym przypadku secondlink). Po trzecie, w ostatniej kolumnie wyświetlana jest nazwa obiektu docelowego, na który wskazuje dowiązanie poprzedzona znaczkiem ->.
Dowiązania symboliczne - szczegółowo
Generalnie dowiązania symboliczne są bardziej elastyczne od dowiązań twardych. Dowiązanie symboliczne może zostać utworzone do jakiegokolwiek obiektu znajdującego się na systemie plików wliczając w to katalogi. Dodatkowo, w związku z tym, że dowiązania symboliczne opierają się na ścieżce (a nie na i-węzłach), to nic nie stoi na przeszkodzie, aby stworzyć dowiązanie symboliczne, które wskazuje na obiekt fizycznie znajdujący się na innym systemie plików. Niemniej jednak ta cecha może sprawić, że dowiązania symboliczne będą trochę trudne do zrozumienia.
Rozważmy sytuację, w której chcemy utworzyć dowiązanie w /tmp, które wskazuje na /usr/local/bin. Moglibyśmy zrobić to tak:
Listing 4.3: Tworzenie dowiązania do katalogu, sposób pierwszy |
$ ln -s /usr/local/bin bin1 $ ls -l bin1 lrwxrwxrwx 1 root root 14 Jan 1 15:42 bin1 -> /usr/local/bin |
lub tak:
Listing 4.4: Tworzenie dowiązania do katalogu, sposób pierwszy |
$ ln -s ../usr/local/bin bin2 $ ls -l bin2 lrwxrwxrwx 1 root root 16 Jan 1 15:43 bin2 -> ../usr/local/bin |
Jak widać, obydwa dowiązania symboliczne wskazują na ten sam katalog. Jednak, jeżeli drugie dowiązanie zostanie kiedykolwiek przeniesione do innego katalogu, to stanie się dowiązaniem "przerwanym" ze względu na ścieżkę względną:
Listing 4.5: Zrywanie dowiązania symbolicznego |
$ ls -l bin2 lrwxrwxrwx 1 root root 16 Jan 1 15:43 bin2 -> ../usr/local/bin $ mkdir mynewdir $ mv bin2 mynewdir $ cd mynewdir $ cd bin2 bash: cd: bin2: No such file or directory |
W związku z tym, że nie istnieje katalog /tmp/usr/local/bin, nie możemy już zmienić katalogu na bin2; innymi słowy bin2 jest teraz zerwanym dowiązaniem.
Z tego właśnie powodu czasami dobrze jest unikać tworzenia dowiązań symbolicznych ze ścieżką względną. Jest wiele przypadków, kiedy ścieżki względne są bardzo pomocne. Weźmy pod uwagę przykład gdzie chcemy stworzyć alternatywną nazwę dla programu w katalogu /usr/bin:
Listing 4.6: Przeglądnie informacji o pliku keychain |
# ls -l /usr/bin/keychain
-rwxr-xr-x 1 root root 10150 Dec 12 20:09 /usr/bin/keychain
|
Jako użytkownik root chcemy stworzyć alternatywną nazwę dla pliku "keychain", np. "kc". W tym przypadku mamy prawa administratora, czego dowodem jest zmiana znaku zachęty na "#". Potrzebujemy praw dostępu administratora, ponieważ zwykły użytkownik nie ma praw do tworzenia plików w /usr/bin. Jako administrator możemy stworzyć alternatywną nazwę dla pliku keychain w następujący sposób:
Listing 4.7: Tworzenie dowiązania symbolicznego do keychain |
# cd /usr/bin # ln -s /usr/bin/keychain kc # ls -l keychain -rwxr-xr-x 1 root root 10150 Dec 12 20:09 /usr/bin/keychain # ls -l kc lrwxrwxrwx 1 root root 17 Mar 27 17:44 kc -> /usr/bin/keychain |
Stworzyliśmy dowiązanie symboliczne o nazwie kc, które wskazuje na plik /usr/bin/keychain.
Takie rozwiązanie działa, ale problemy zaczną się wtedy gdy zdecydujemy przenieść obydwa pliki, /usr/bin/keychain oraz /usr/bin/kc do katalogu /usr/local/bin:
Listing 4.8: Przenoszenie dowiązania symbolicznego |
# mv /usr/bin/keychain /usr/bin/kc /usr/local/bin # ls -l /usr/local/bin/keychain -rwxr-xr-x 1 root root 10150 Dec 12 20:09 /usr/local/bin/keychain # ls -l /usr/local/bin/kc lrwxrwxrwx 1 root root 17 Mar 27 17:44 kc -> /usr/bin/keychain |
Ponieważ w dowiązaniu zastosowaliśmy ścieżkę bezwzględną, to dowiązanie kc cały czas wskazuje na plik /usr/bin/keychain, który już nie istnieje ponieważ przenieśliśmy go do /usr/local/bin.
Oznacza to, że kc jest teraz dowiązaniem błędnym. Zarówno ścieżki względne jak i bezwględne w dowiązaniach symbolicznych posiadają swoje zalety i powinno się stosować takie rodzaje ścieżek, które są najbardziej odpowiednie dla konkretnego zastosowania. Najczęściej oba rodzaje ścieżek będą dobre. Poniższy przykład będzie działał nawet wtedy gdy obydwa pliki zostaną przeniesione:
Listing 4.9: Przenoszenie plików z dowiązaniami symbolicznymi |
# cd /usr/bin # ln -s keychain kc # ls -l kc lrwxrwxrwx 1 root root 8 Jan 5 12:40 kc -> keychain # mv keychain kc /usr/local/bin # ls -l /usr/local/bin/keychain -rwxr-xr-x 1 root root 10150 Dec 12 20:09 /usr/local/bin/keychain # ls -l /usr/local/bin/kc lrwxrwxrwx 1 root root 17 Mar 27 17:44 kc -> keychain |
Jak widać, możemy uruchomić program keychain poprzez wpisanie /usr/local/bin/kc. /usr/loca/bin/kc wskazuje na program keychain, który znajduje się w tym samym katalogu.
Teraz, gdy wiemy już jak używać poleceń cp, mv oraz ln, nadszedł czas aby nauczyć się jak usuwać obiekty z systemu plików. Dokonuje się tego za pomocą polecnia rm. W celu usunięcia pliku należy wskazać go po prostu wskazać w linii poleceń:
Listing 4.10: Usuwanie plików |
$ cd /tmp $ touch file1 file2 $ ls -l file1 file2 -rw-r--r-- 1 root root 0 Jan 1 16:41 file1 -rw-r--r-- 1 root root 0 Jan 1 16:41 file2 $ rm file1 file2 $ ls -l file1 file2 ls: file1: No such file or directory ls: file2: No such file or directory |
Należy pamiętać o tym, że w Linuksie jeżeli dany plik zostanie usunięty za pomocą polecenia rm to z reguły jest to nieodwracalne. Dlatego też wielu początkujących administratorów systemu powinno korzystać z opcji -i podczas usuwania plików. Opcja -i sprawia, że polecenie rm usuwa pliki w trybie interaktywnym, czyli pyta przed usunięciem pliku. Przykład:
Listing 4.11: Usuwanie plików z pytaniem o potwierdzenie |
$ rm -i file1 file2
rm: remove regular empty file `file1'? y
rm: remove regular empty file `file2'? y
|
W powyższym przykładzie polecenie rm pyta czy na pewno ma usunąć pliki. W celu ich usunięcia muszę dwukrotnie wpisać "y" i nacisnąć Enter. Gdybym wpisał "n" plik nie zostałby usunięty. Mógłbym też, jeżeli zrobiłbym naprawdę coś złego, wcisnąć Control-C, co całkowicie przerwałoby wykonywanie polecenia rm -i, zanim zdążyłoby ono dokonać potencjalnych zniszczeń w moim systemie.
Jeżeli wciąż staramy się przywyknąć do polecenia rm, to pomocnym może być wpisanie przy pomocy swojego ulubionego edytora tekstu następującej linii do pliku ~/.bashrc, a następnie wylogowanie się i ponowne zalogowanie. Wtedy za każdym razem gdy wydane zostanie polecenie rm, powłoka bash automatycznie zmieni to polecenie w polecenie rm -i. Tym sposobem polecenie rm zawsze będzie działać w trybie interaktywnym:
Listing 4.12: Ustawianie aliasu 'rm -i' |
alias rm="rm -i"
|
Istnieją dwa sposoby na usunięcie katalogów. Pierwsza to usunięcie wszystkich obiektów wewnątrz katalogu, a potem za pomocą polecenia rmdir usunięcie samego katalogu.
Listing 4.13: Usuwanie katalogów |
$ mkdir mydir $ touch mydir/file1 $ rm mydir/file1 $ rmdir mydir |
Metoda ta jest powszechnie znana pod nazwą "usuwanie katalogów dla frajerów". Wszyscy biegli użytkownicy i administratorzy z prawdziwego zdarzenia stosują o wiele bardziej wygodne polecenie rm -rf opisane poniżej.
Najlepszą metodą na usunięcie katalogu jest użycie opcji recursive force dla polecenia rm, które to opcje sprawiają, że rm usuwa wskazany katalog wraz z zawartością:
Listing 4.14: Usuwanie katalogu z zawartością |
$ rm -rf mydir
|
Zazwyczaj polecenie rm -rf jest preferowaną metodą usuwania całego drzewa katalogów. Trzeba być bardzo ostrożnym przy korzystaniu z polecenia rm -rf ponieważ siła tego narzędzia może być wykorzystana zarówno dla dobrych jak i złych rzeczy.
5. Używanie znaków wieloznacznych
Wprowadzenie do znaków wieloznacznych
Podczas codziennego korzystania z Linuksa wielokrotnie spotkamy się z potrzebą przeprowadzenia jakiejś operacji (np. rm) na wielu plikach jednocześnie. W takich przypadkach najczęściej jest bardzo niewygodnym wpisywanie wszystkich plików w linii poleceń:
Listing 5.1: Usuwanie wielu plików |
$ rm file1 file2 file3 file4 file5 file6 file7 file8
|
Z tego powodu, można wykorzystać wbudowaną w Linuksa obsługę znaków wieloznacznych. Obsługa ta po angielsku nazywana "globbing" (z powodów historycznych), pozwala na wskazanie kilku plików na raz za pomocą wzorca wieloznacznego. Bash i inne polecenia Linuksa zinterpretują ten wzorzec szukacjąc na dysku wszystkich plików, które pasują do tego wzorca. Innymi słowy, jeżeli mamy pliki file1 do file8 w bieżącym katalogu, wtedy można je usunąć za pomocą polecenia:
Listing 5.2: Usuwanie plików z wykorzystaniem uzupełniania nazw plików przez powłokę |
$ rm file[1-8]
|
Jeżeli po prostu chcemy usunąć pliki, których nazwa zaczyna się od file jak również plik, który nazywa się file, to możemy po prostu wpisać:
Listing 5.3: Usuwanie plików z wykorzystaniem uzupełniania i symbolu wieloznacznego * |
$ rm file*
|
Do symbolu wieloznacznego * pasuje dowolny znak lub sekwencja znaków lub nawet nic, czyli żaden znak. Symbole wieloznaczne wykorzystywane są do wielu więcej czynności niż tylko do usuwania plików co zostanie omówione w następnym paragrafie.
Gdybyśmy chcieli wylistować wszystkie obiekty w /etc zaczynające się na literę g jak również te, które nazywają się g, wydalibyśmy następujące polecenie:
Listing 5.4: Przykładowe zastosowanie znaku wieloznaczengo * |
$ ls -d /etc/g*
/etc/gconf /etc/ggi /etc/gimp /etc/gnome /etc/gnome-vfs-mime-magic /etc/gpm /etc/group /etc/group-
|
Co by się stało, gdybyśmy podali wzorzec, do którego nie będzie pasował żaden obiekt w systemie plików? W poniższym przykładzie spróbujemy wydrukować listę wszystkich plików w /usr/bin, które zaczynają się od asdf i kończą jkl, włączając w to ewentualny plik asdfjkl:
Listing 5.5: Kolejny przykład zastosowania znaku wieloznacznego * |
$ ls -d /usr/bin/asdf*jkl
ls: /usr/bin/asdf*jkl: No such file or directory
|
Oto co się stało. Zwykle kiedy podajemy wzorzec, pasuje do niego jeden lub więcej plików, a bash zamienia wzorzec na oddzieloną spacjami listę wszystkich pasujących do wzorca obiektów. Kiedy jednak nic nie pasuje do podanego wzorca, wtedy bash pozostawia wszystko, łącznie ze znakami wieloznacznymi tak jak zostały wpisane. Wtedy polecenie ls nie może znaleźć pliku o nazwie /usr/bin/asdf*jkl i wyświetli komunikat o błędzie. Zasadą, która tu zadziałała jest to, że wzorce wieloznaczne są podmieniane tylko wtedy gdy będzie do nich pasował obiekt systemu plików. W przeciwnyn razie wzorzec pozostawiany jest dokładnie tak jak został wpisany i jest przekazywany literalnie.
Składnia wyrażeń wieloznacznych: * i ?
Skoro wiemy już jak działa dopasowanie do wzorca, powinniśmy przyjrzeć sie składni wyrażeń wieloznacznych. Do rozwijania wyrażeń wieloznacznych stosowane są znaki specjalne.
* zastępuje wiele znaków lub żaden znak. Oznacza to "zamiast * można podstawić * wszystko łącznie z niczym". Przykład:
Znak ? zastępuje dwolny dokładnie jeden znak. Przykład:
Składnia wyrażeń wieloznacznych: []
Symbol wieloznaczny [] jest podobny do ?, jest jednak bardziej szczegółowy. Wykorzystanie tego symbolu wieloznacznego polega na wstawieniu między [ i ] wszystkich znaków, które chcemy dopasować. Wyrażenie powstałe w wyniku takiej operacji będzie pasowało do każdego występującego wstawionego znaku. Można także zastosować znak -, aby określić zakres znaków, jak również można nawet wstawiać wiele zakresów. Przykłady:
Konstrukcja [!] jest podobna do [], z tą tylko różnicą, że poszukiwane będzie dopasowanie nie do znaków pomiędzy nawiasami, lecz do wszystkich innych znaków, niż te wyspecyfikowane pomiędzy [! i ]. Przykład:
Uwagi do znaków wieloznacznych
Podczas stosowania znaków wieloznacznych należy uważać na kilka pułapek. W związku z tym, że bash traktuje symbole wieloznaczne (?, [, ] oraz *) w specjalny sposób, należy zwrócić szczególną uwagę na wpisywanie argumentów poleceń, które zawierają tego rodzaju znaki. Jeżeli np. chcielibyśmy stworzyć plik, który zawierałby ciąg znaków [fo*], to wykonanie poniższego polecenia niekoniecznie dałoby spodziewany rezultat:
Listing 5.6: Niepoprawne zastosowanie znaków specjalnych |
$ echo [fo]* > /tmp/mynewfile.txt
|
Jeżeli wzorzec [fo]* pasowałby do jakichkolwiek plików w katalogu bieżącym, to w pliku /tmp/mynewfile.txt znalazłyby się wszystkie nazwy pasujących do wzorca plików, a nie, jak się spodziewaliśmy, ciąg znaków [fo]*. Rozwiązanie? Cóż, jeden sposób, to zamknięcie tego ciągu znaków w pojedynczy cudzysłów, który sprawi, że bash nie dokona żadnego rozwinięcia symboli wieloznacznych:
Listing 5.7: Unieważnianie znaków specjalnych |
$ echo '[fo]*' > /tmp/mynewfile.txt
|
Przy zastosowaniu takiego sposobu mynewfile.txt będzie zawierał dokładnie ciąg znaków [fo]*, tak jak tego oczekiwaliśmy. Drugi sposób to zastosowanie sekwencji ucieczki, w celu przekazania informacji dla powłoki bash, aby traktowała znaki [, ] oraz * literalnie, a nie jako znaki wieloznaczne:
Listing 5.8: Unieważnianie znaków specjalnych, sposób drugi |
$ echo \[fo\]\* > /tmp/mynewfile.txt
|
Obydwa sposoby (zastosowanie pojedynczego cudzysłowiu i sekwencji ucieczki) dają ten sam efekt. Skoro już mówimy o unieważnianiu lewym ukośnikiem, to jest to dobry moment na to aby wspomnieć, że w celu podania znaku \ należy go również zamknąć w pojedynczy cudzysłów lub też wpisać \\ (co zostanie rozwinięte do \).
Uwaga: Cudzysłów podwójnego cudzysłowu działa podobnie do pojedynczego, z tą różnicą, że pozwala on na dokonywanie pewnego zakresu rozwijania symboli specjalnych. Dlatego też, w przypadku gdy chcemy literalnie przekazać ciąg znaków, najlepszym do tego narzędziem jest cudzysłów pojedynczy. W celu uzyskania bardziej wyczerpujących informacji na temat rozwijania symboli wieloznacznych można wpisać man 7 glob. Więcej informacji na temat stosowania cudzysłowów nalezy wpisać man 8 glob i przeczytać rozdział QUOTING. Jeżeli ktoś chce podchodzić do egzaminu LPI, to niech to potraktuje jako zadanie domowe. :) |
6. Podsumowanie i zasoby informacji
Gratulacje; właśnie doszliśmy do końca przeglądu Podstaw Linuksa! Mam nadzieję, że pomogło to w utrwaleniu podstawowej wiedzy na temat Linuksa. Tematy, które zostały omówione, wliczając w to podstawy basha, podstawowe polecenia, dowiązania i symbole wieloznaczne stanowią przygotowanie do następnego materiału na temat podstaw administrowania, w którym zostaną omówione zagadnienia takie jak wyrażenia regularne, prawa własności i prawa dostępu, zarządzanie kontami użytkowników i inne.
Poznając dalszy ciąg serii tych materiałów będzie można dojść do pierwszego poziomu egzaminu LPIC. Jeżeli ktoś jest zainteresowany przystąpieniem do tego egzaminu to powinien zapoznać się z Zasobami informacji z następnego rozdziału, które zostały specjalnie wybrane jako rozszerzenie wiadomości omówionych w tym wprowadzeniu.
W serii artykułów "Bash w przykładach" Daniel omawia w jaki sposób korzystać ze składni programowania w bashu w celu pisania własnych skryptów. Seria ta (zwłaszcza część 1 i 2) będzie znakomitym przygotowaniem do egzaminu LPIC pierwszego poziomu:
Każdy początkujący lub średnio zaawansowany użytkownik Linuksa powinien zapoznać się z Technical FAQ for Linux users, 50 stronicową listą najczęściej zadawanych pytań dotyczących Linuksa wraz ze szczegółowymi odpowiedziami. Publikacja ta jest w formacie PDF (Acrobat).
Jeżeli ktoś nie zna edytora vi, to powinien zapoznac się z wprowadzeniem do vi na developerWorks. Artykuł delikatnie, lecz szybko wprowadza czytelnika w podstawy tego potężnego edytora. Dla wszystkich, którzy nie znają edytora vi jest to lektura obowiązkowa.