Pliki

Pliki

To ćwiczenie demonstruje zachowania typowe dla uniksowych systemów plików. Proszę mieć na uwadze fakt, że użycie niektórych operacji w kontekście innych systemów plików (np. pendrive z systemem FAT) może zakończyć się błędem z informacją, że dana operacja nie jest obsługiwana.

i-węzły

Podstawową strukturą opisującą plik w systemie plików jest i-węzeł (i-node). i-węzeł zawiera co najmniej następujące informacje o pliku:

Ponadto każdy i-węzeł ma numer porządkowy, po którym można go odróżnić od pozostałych. Proszę zwrócić uwagę, że nie ma tu nazwy pliku

Aby zawartość pliku była w jakiś sposób dostępna dla użytkownika, konieczne jest istnienie dowiązań do i-węzła – wpisu w katalogu składającego się z nazwy pliku i numeru i-węzła na który wskazuje ta nazwa. Inaczej: każdy wpis (plik) w katalogu, to w rzeczywistości para (nazwa, numer i-węzła). Teoretycznie można utworzyć wiele dowiązań z wielu katalogów do pojedynczego i-węzła – nazywamy je dowiązaniami twardymi (hard links).

Pole typ pliku specyfikuje jaki rodzaj pliku opisuje i-węzeł (w nawiasach literowe oznaczenie typu używane np. przez ls -l):

symlinki i linki (twarde)

Link twardy jest wpisem w katalogu wskazującym na dany inode. Żeby plik nie został usunięty musi istnieć przynajmniej jedno wskazanie na niego. Link twardy może istnieć tylko w obrębie fizycznego systemu plików (w przybliżeniu: katalog w którym jest wpis i inode muszą być na tej samej partycji).

Symlink (dowiązanie symboliczne, link symboliczny) to wskazanie na inny plik przez ścieżkę. Symlink posiada własny inode, niezależny od wskazywanego pliku i jest odróżnialny od właściwego pliku. Z racji odniesienia przez ścieżkę symlinki działają pomiędzy systemami plików, ale w przypadku usunięcia lub zmiany nazwy pliku docelowego stają się nieaktualne. W praktyce używa się symlinków, poza specyficznymi przypadkami.

Do tworzenia dodatkowych linków twardych i symlinków służy program ln, który z opcją -s tworzy linki symboliczne, bez – twarde. Przyjmuje dwa argumenty – plik do którego utworzyć link i ścieżkę do tworzonego linku.

$ echo test > test # utworzenie pliku
$ ln test nowa_nazwa
$ echo Test2 >> nowa_nazwa
$ cat test
$ cat nowa_nazwa # ta sama zawartość
$ ln -s test nazwa3
$ cat nazwa3
$ rm test
$ cat nazwa3 # nie ma pliku
$ cat nowa_nazwa # OK

Otwarte pliki

Program lsof pozwala wyświetlić listę plików otwartych przez różne programy (uwaga: bez uprawnień administratora lista będzie niepełna – nie zawiera niektórych informacji o innych użytkownikach).

$ lsof

Proszę mieć na uwadze, że to że jakiś program (np. edytor tekstu) wyświetla zawartość pliku, to niekoniecznie znaczy, że plik jest otwarty, może być tak, że program otworzył plik, przekopiował zawartość do bufora w pamięci i zamknął plik.

Usuwanie pliku następuje, gdy nie ma już żadnych odniesień do i-węzła, odniesienia to: dowiązania twarde i deskryptory otwartych plików. Inaczej: usunięcie pliku z katalogu nie powoduje zwolnienia i-węzła i zajmowanego przez dane pliku miejsca do momentu zamknięcia tego pliku przez wszystkie programy.

Operacje administracyjne

Widziana struktura katalogów, rozpoczynając od korzenia – / jest efektem działania Vitrual File System (VFS ,wirtualnego systemu plików). Mechanizm ten pozwala na połączenie w spójne drzewo katalogów różnych systemów plików pochodzących z wielu dysków twardych, dysków zewnętrznych, udziałów sieciowych, wirtualnych systemów plików, itp.

Jedną z podstawowych operacji w kontekście VFS jest montowanie (mount), realizowane przez programy mount i umout. W większości programów te operacji są niedostępne dla zwykłych użytkowników. Operacja montowania powoduje dodanie do drzewa wirtualnego systemu plików zawartości nowego systemu plików (np. nowej partycji) w danym katalogu. Przykład uzycia: zawartość partycji /dev/sdb1 będzie teraz widoczna w katalogu /var/www:

# mount /dev/sdb1 /var/www

Za pomocą programu umount można zakończyć mapowanie do danego katalogu (i upewnić się, że wszystkie zmiany zostały zapisane). Na przykład w momencie odłączania dysku wymiennego, sieci.

# umount /var/www
# # lub
# umount /dev/sdb1

Zanim dysk twardy będzie mógł być użyty, należy go podzielić na partycje, można się posłużyć narzędziem fdisk. Do formatowania partycji służy program mkfs -t typ.

Użycie miejsca na dysku

Miejsce na systemie plików jest zorganizowane w bloki. Każdy plik zajmuje całkowitą liczbę bloków, rozmiar bloku jest ustawiany dla systemu plików w momencie jego tworzenia (formatowania). Oznacza to, że plik o długości np. 1 bajta i tak zajmuje cały blok przestrzeni dyskowej.

Poza blokami związanymi z fizycznym układem danych na dysku, poprzez blok (block) standard w standardzie POSIX rozumiana jest jednostka 512 bajtów. Wszystkie POSIXowe narzędzia wypisujące rozmiary plików powinny posługiwać się właśnie tą jednostką. Uwaga! Twórcy narzędzi GNU uznali 512 blok za nieintuicyjny. Te narzędzia (zainstalowane np. w laboratorium) używają rozmiaru bloku 1024 bajty (1KiB). To zachowanie można zmienić, ustawiając zmienną środowiskową POSIXLY_CORRECT=1.

Program df pozwala na sprawdzenie ilości wolnego miejsca na dysku, w przypadku udziałów sieciowych podawane informacje mogą nie być zgodne z prawdą. (Nie zawsze oznacza to, że bieżący użytkownik może dysponować tak dużą przestrzenią, mogą być dodatkowe ograniczenia). Domyślnie df wyświetli użycie miejsca na wszystkich zamontowanych systemach plików. Za pomocą parametru wywołania – nazwy pliku można zobaczyć dostępną przestrzeń na systemie, gdzie znajduje się dany plik. Domyślnie jednostką wyjściową df są bloki, można ustawić wyjście przyjazne dla człowieka – opcja -h.

$ df
$ df
$ df -h
$ df /etc
$ df -h ~
$ export POSIXLY_CORRECT=1
$ df # inne wyniki niż bez POSIXLY_CORRECT=1
$ unset -v POSIXLY_CORRECT # usunięcie zmiennej

Program du pozwala sprawdzić zajętość miejsca przez pliki i katalogi. Można podać dowolnie dużo nazw jako argumenty. Podobnie jak df domyślnie wyświetla wyniki w blokach, opcja -h podaje wyniki w postaci przyjaznej dla człowieka. Domyślnie podany jest rozmiar wynikający z liczby bloków zajętych przez plik (bloków systemu plików, a nie POSIX), zachowanie to można zmienić opcją -b.

$ du /etc/passwd
$ du -h /etc/passwd
$ du -hb /etc/passwd
$ du -h ~/Desktop # katalog

program dd

Przy pracy z dyskami twardymi (lub innymi urządzeniami blokowymi), często potrzebna jest możliwość skopiowania konkretnego fragmentu dysku (lub całości) bajt po bajcie. Popularnym narzędziem do tego celu jest dd.

$ dd if=/dev/sdb of=moja_kopia bs=1024 count=10 # kopiuje 10 bloków po
$ # 1024 bajty z urządzenia /dev/sdb do pliku moja_kopia
  1. Utworzyć plik tekstowy file.txt. Sprawdzić jego cechy poleceniem:

    $ stat file.txt

    Zwrócić uwagę na numer i-węzła i czasy. Zmienić nazwę pliku i ponownie sprawdzić jego parametry. Czy coś się zmieniło? Przenieść plik do innego katalogu. Sprawdzić parametry. Otworzyć plik, zmodyfikować zawartość, sprawdzić z użyciem stat. Przenieść plik do katalogu /tmp (który znajduje się na innym systemie plików niż /home). Uruchomić stat na przeniesionym pliku. Jaki jest numer i-węzła?

    Jest różnica między przenoszeniem pliku w obrębie jednego systemu plików i pomiędzy systemami plików (np. dyskami, partycjami). W drugim przypadku plik (również jego dane) muszą zostać skopiowane w inne miejsce, a stary plik usunięty (w zasadnie usunięte będzie jedno dowiązanie, jeśli jest więcej hardlinków, plik zostanie).

  2. tego ćwiczenia nie uda się zrobić na serwerze ze względu na limity miejsca oraz układ partycji. Przenoszenie plików w obrębie i pomiędzy fs – czas działania. Za pomocą programu dd utworzyć plik zawierający losowe dane o rozmiarze 100MB, za pomocą polecenia time zmierzyć czas zmiany nazwy (przenoszenia w obrębie systemu plików) i przenoszenia między systemami plików.

    $ dd if=/dev/urandom of=my_large_file bs=1024 count=102400
    $ du -h my_large_file
    $ stat my_large_file
    $ time mv my_large_file my_large_file2
    $ stat my_large_file2
    $ time mv my_large_file2 /tmp/
    $ stat /tmp/my_large_file2 # oczywiście zmienił się inode
  3. Zaobserwować istnienie plików urządzeń – katalog /dev:

    $ cd /dev
    $ stat sda # główny hdd
    $ stat input/mouse0 # mysz
    $ stat zero 
    $ stat random
    $ stat null

    Trzy ostatnie to przykłady urządzeń specjalnych. Nie reprezentują żadnych fizycznych urządzeń, ale mają specjalne funkcje:

    • zero generuje nieskończony ciąg zerowych bajtów
    • random generuje nieskończony ciąg losowych bajtów
    • null urządzenie, które jest zawsze puste i przyjmie dowolną ilość danych (zapominając je natychmiast). Użyteczne przy ignorowaniu wyjścia programu poprzez przekierowanie do tego urządzenia.
    $ ls -l /dev

Pierwsza litera symbolicznego trybu pliku (c lub b) oznacza odpowiednio urządzenie znakowe (character) lub blokowe. Zaobserwować, że większość urządzeń stanowią urządzenia znakowe. Zaobserwować zróżnicowane uprawnienia do urządzeń.

  1. Dowiązania symboliczne. Utworzyć, np. edytorem nano przykładowy plik z zawartością do testów. Utworzyć symlink do tego pliku:

    $ ln -s plik nowa_nazwa

    Za pomocą stat obejrzeć plik i symlink. Czy mają taki sam numer inode? Obejrzeć zawartość pliku z użyciem cat. Czy są różnice? Spróbować edytować zawartość używając jednej i drugiej nazwy. Jakie są efekty?

    Przenieść symlink do katalogu /tmp z użyciem mv. Czy dalej działa? Symlinki używają ścieżek względnych, jeśli zostały utworzone poprzez podanie względnej ścieżki w poleceniu ln. Zmienić właściwy plik. Przenieść symlink z powrotem. Jaka jest zawartość plików?

    Spróbować utworzyć symlink do nieistniejącego pliku.

    Usunąć właściwy plik. Spróbować dopisać coś do symlinku z użyciem >>

  2. Dowiązania twarde. Utworzyć plik do testów i utworzyć dowiązanie twarde:

    $ ln plik nowa_nazwa # tym razem bez -s

    Za pomocą stat obejrzeć plik i link. Czy mają taki sam numer inode? Obejrzeć zawartość pliku z użyciem cat. Czy są różnice? Spróbować edytować zawartość używając jednej i drugiej nazwy. Jakie są efekty?

    Przenieść link do katalogu /tmp z użyciem mv. Zmienić plik w /tmp i w katalogu domowym. Czy link dalej działa? Przenieść plik z /tmp z powrotem do bieżącego katalogu. Czy to coś pomogło?

    Spróbować utworzyć twarde dowiązanie do katalogu.

    Uwaga! Należy unikać używania dowiązań twardych!

  3. Wywołać ploecenie mount i znaleźć informacje o udziałach sieciowych:

    $ mount
  4. Tego ćwiczenia nie da się zrobić na serwerze ze względu na limity miejsca na dysku Zwalnianie miejsca, a otwarte pliki. Program less utrzymuje otwarty deskryptor pliku aż do momentu zamknięcia less. Utworzyć duży plik (1000 MB) w katalogu /tmp i sprawdzić ilość zajętego miejsca.

    $ cd /tmp
    $ dd if=/dev/urandom of=my_large_file bs=1024 count=1024000
    $ df -h /tmp  # zapamiętać ile jest miejsca

    Otworzyć plik z użyciem programu less. Nie przejmować się, że to dane binarne. Pozostawić okno terminalna z otwartym programem less. Otworzyć drugi emulator terminala:

    $ cd /tmp
    $ df -h /tmp
    $ rm my_large_file
    $ df -h /tmp # czy coś się zwolniło?

    Zamknąć program less i sprawdzić wolne miejsce ponownie.

  5. Wywołać stat na kilku plikach i katalogach. Znaleźć wartość Links oznaczającą liczbę dowiązań do pliku. Ta wartość zwraca liczbę dowiązań twardych do pliku.

    Jakie są wartości dla katalogów? Utworzyć testowe podkatalogi. Czy wpływają one na liczbę dowiązań do katalogu nadrzędnego? .. w katalogu podrzędnym jest liczone do sumy dowiązań.