Przejdź do treści
Lekcja 14 z 117

Kurs › Moduł 1 › Lekcja 14

Linki: skróty, które nie są skrótami

⏱ ok. 9 min czytania· moduł 1: Praca w powłoce

Po tej lekcji: kursant wie, co to jest i-węzeł, robi link twardy i symboliczny, przewiduje, co się stanie po usunięciu oryginału, i umie sprawdzić, dokąd naprawdę prowadzi link.

Wstęp

dwa pliki obok siebie w ls -li, ta sama liczba na początku obu linijek

Zmieniasz coś w jednym pliku, a zmienia się drugi. Kasujesz plik, a on dalej jest. Kasujesz inny i nagle trzeci przestaje działać. Na dysku jest wolne 90 procent miejsca, a system krzyczy „brak miejsca”.

To nie duchy. To linki i i-węzły. Po tej lekcji każda z tych zagadek będzie miała proste wyjaśnienie, a Ty zobaczysz, jak plik wygląda od środka.

Nazwa to nie plik

Wyobraź sobie bibliotekę. Książki stoją w magazynie i każda ma numer, powiedzmy 983049. Na półce z katalogiem są karteczki: „Pan Tadeusz → 983049”. Karteczka to nie książka. To tylko nazwa i numer.

W Linuksie jest dokładnie tak. Folder to katalog z karteczkami: nazwa pliku i numer. A pod numerem leży prawdziwa karta pliku. Ta karta nazywa się i-węzeł, po angielsku inode. Zapisane są w nim: kto jest właścicielem, jakie są uprawnienia, jaki rozmiar, kiedy zmieniany i gdzie na dysku leżą kawałki treści. Czego w i-węźle nie ma? Nazwy. Nazwa mieszka tylko w folderze.

Numer i-węzła pokazuje ls -i:

mkdir ~/linki && cd ~/linki
echo "Kup mleko" > notatka.txt
ls -i notatka.txt
983049 notatka.txt

A całą kartę wyciąga stat:

stat notatka.txt
  File: notatka.txt
  Size: 10        	Blocks: 8          IO Block: 4096   regular file
Device: 254,0	Inode: 983049      Links: 1
Access: (0664/-rw-rw-r--)  Uid: (30042/    eryk)   Gid: (30043/    eryk)
Access: 2026-11-03 21:12:45.623824092 +0000
Modify: 2026-11-03 21:12:45.628670144 +0000
Change: 2026-11-03 21:12:45.628670144 +0000
 Birth: 2026-11-03 21:12:45.623824092 +0000

Popatrz na Links: 1. Tyle karteczek w katalogach wskazuje na tę książkę. Zaraz to zmienimy.

ln notatka.txt kopia.txt
ls -li
983049 -rw-rw-r-- 2 eryk eryk 10 Nov  3 21:12 kopia.txt
983049 -rw-rw-r-- 2 eryk eryk 10 Nov  3 21:12 notatka.txt

ln bez żadnej flagi robi link twardy. Ten sam numer i-węzła, a w drugiej kolumnie ls -l dwójka. To ta kolumna, którą do tej pory pomijałeś: licznik karteczek.

I tu pierwsza zagadka z haka. Dopisuję coś do „kopii”:

echo "i chleb" >> kopia.txt
cat notatka.txt
Kup mleko
i chleb

Bo to nie jest kopia. To ta sama książka z dwiema karteczkami w katalogu. Nie ma oryginału i kopii, obie nazwy są równie ważne. Jak bliźniaki, tylko jeszcze bardziej: to jeden człowiek z dwoma dowodami osobistymi.

ln -s notatka.txt skrot.txt
ls -li
983049 -rw-rw-r-- 2 eryk eryk 18 Nov  3 21:12 kopia.txt
983049 -rw-rw-r-- 2 eryk eryk 18 Nov  3 21:12 notatka.txt
983050 lrwxrwxrwx 1 eryk eryk 11 Nov  3 21:12 skrot.txt -> notatka.txt

ln -s robi link symboliczny, po polsku też dowiązanie symboliczne, w mowie adminów „symlink”. To już jest osobny plik, z własnym numerem i-węzła, a na początku uprawnień ma literkę l. W środku nie ma treści notatki, tylko adres: „szukaj w notatka.txt”. Rozmiar 11 bajtów, bo tyle liter ma ten adres.

To jest właśnie skrót z Windowsa. Kartka „Pan Tadeusz stoi w dziale polskim, regał 3”. Ten drogowskaz poznałeś już w lekcji 8, kiedy /bin pokazywał na usr/bin, i w lekcji 9, kiedy sh okazał się dashem.

Co się dzieje po usunięciu oryginału

I teraz test, który odróżnia tych, co rozumieją linki, od tych, co tylko je robią.

rm notatka.txt
ls -li
cat kopia.txt
cat skrot.txt
983049 -rw-rw-r-- 1 eryk eryk 18 Nov  3 21:12 kopia.txt
983050 lrwxrwxrwx 1 eryk eryk 11 Nov  3 21:12 skrot.txt -> notatka.txt
Kup mleko
i chleb
cat: skrot.txt: No such file or directory

rm nie usuwa pliku. rm wyrzuca karteczkę z katalogu i zmniejsza licznik. Licznik spadł z 2 na 1, więc książka dalej stoi w magazynie, a kopia.txt działa bez zarzutu. Treść zniknie dopiero wtedy, gdy licznik spadnie do zera.

A symlink? Prowadzi pod adres notatka.txt, a pod tym adresem nikogo już nie ma. Drogowskaz do zamkniętego sklepu. Taki link nazywa się wiszący, po angielsku dangling albo broken. W kolorowym ls świeci na czerwono, w mc ma wykrzyknik. Brzmi znajomo?

Wystarczy z powrotem utworzyć plik o tej nazwie i link ożyje. On nie pamięta pliku, pamięta tylko adres.

readlink skrot.txt
readlink -f skrot.txt
ln -s /etc/os-release system
readlink system
readlink -f system
notatka.txt
/home/eryk/linki/notatka.txt
/etc/os-release
/usr/lib/os-release

Samo readlink czyta, co jest napisane na kartce. readlink -f idzie za wszystkimi drogowskazami po kolei i podaje pełną, ostateczną ścieżkę. Zobacz: /etc/os-release to też symlink, który prowadzi do /usr/lib/os-release. Właśnie dlatego w zadaniu mc skopiował drogowskaz.

Kiedy który link? Symlinków używasz w 95 procentach przypadków: do folderów, między dyskami, do przełączania wersji. Na przykład aktualna -> wersja-2.4, a przy aktualizacji tylko przestawiasz strzałkę. Twarde linki spotkasz rzadziej, głównie w narzędziach do kopii zapasowych, które w ten sposób trzymają sto kopii folderu, a każdy niezmieniony plik zajmuje miejsce tylko raz.

ln /etc etc_twardy
ln kopia.txt /dev/shm/kopia.txt
ln: /etc: hard link not allowed for directory
ln: failed to create hard link '/dev/shm/kopia.txt' => 'kopia.txt': Invalid cross-device link

Po pierwsze: żadnych twardych linków do folderów. Gdyby się dało, mógłbyś zrobić folder, który zawiera sam siebie, i find krążyłby w kółko do emerytury. Po drugie: tylko w obrębie jednego systemu plików. Numer i-węzła to numer w magazynie konkretnego dysku. Numer 983049 na innym dysku to zupełnie inna książka. /dev/shm żyje w pamięci RAM, więc to inny magazyn.

Symlink nie ma tych ograniczeń. Może prowadzić do folderu, na inny dysk, a nawet donikąd.

Jak to działa pod spodem

Każdy system plików, na przykład ext4 na Ubuntu czy XFS na RHEL, ma tablicę i-węzłów. Folder na dysku to dosłownie lista par: nazwa i numer i-węzła. ln dopisuje do folderu nową parę i podbija licznik w i-węźle. rm w środku wywołuje funkcję jądra o wymownej nazwie unlink, czyli „odlinkuj”: usuwa parę i zmniejsza licznik.

Treść pliku znika, kiedy spełnione są dwa warunki: licznik linków spada do zera i żaden program nie trzyma pliku otwartego. Ten drugi warunek to klasyka awarii. Usuwasz wielki log, a miejsca nie przybywa, bo program dalej do niego pisze:

ls -l /proc/14581/fd/4
lr-x------ 1 eryk eryk 64 Nov  3 22:12 /proc/14581/fd/4 -> /home/eryk/kurs/t2.txt (deleted)

Plik usunięty, a proces numer 14581 wciąż go trzyma. Wrócimy do tego w module o awariach.

I druga klasyka. I-węzłów jest skończona liczba, ustalona przy tworzeniu systemu plików. Milion maleńkich plików może je wyczerpać, zanim skończą się bajty. Sprawdzasz to przez df -i. Zrobiłem malutki dysk w pamięci z miejscem na 10 i-węzłów:

touch: cannot touch 'plik10': No space left on device
Filesystem      Size  Used Avail Use% Mounted on
tmpfs            10M     0   10M   0% /home/eryk/mini
Filesystem     Inodes IUsed IFree IUse% Mounted on
tmpfs              10    10     0  100% /home/eryk/mini

Zero procent zajętego miejsca, sto procent zajętych i-węzłów i komunikat „brak miejsca”. Biblioteka z pustymi półkami, w której skończyły się numerki. Jak df -h mówi, że jest miejsce, a system twierdzi, że nie ma, od razu df -i.

Ściąga flag

KomendaFlagaCo robi
ls-ipokazuje numer i-węzła
ls-ldruga kolumna to licznik twardych linków, l na początku to symlink
stat(bez flag)cała karta pliku: i-węzeł, linki, uprawnienia, daty
stat-c '%i %h %n'tylko wybrane pola: numer i-węzła, liczba linków, nazwa
ln(bez flag)link twardy
ln-slink symboliczny
ln-sfsymlink, nadpisz istniejący (przestawianie strzałki)
readlink(bez flag)co jest zapisane w symlinku
readlink-fpełna, ostateczna ścieżka po wszystkich strzałkach
find-samefile plikwszystkie twarde linki do tego samego i-węzła
find-xtype lwiszące symlinki
df-izajętość i-węzłów

⚠ Typowy błąd

Symlink ze ścieżką względną zrobiony z innego folderu.

mkdir projekt
echo hej > projekt/plik.txt
ln -s projekt/plik.txt projekt/link.txt
cat projekt/link.txt
cat: projekt/link.txt: No such file or directory

Intuicja mówi: przecież projekt/plik.txt istnieje. Ale adres w symlinku jest liczony od miejsca, w którym leży link, a nie od miejsca, w którym stałeś, kiedy go robiłeś. Link leży w projekt, więc szuka projekt/projekt/plik.txt. Kartka w szufladzie z napisem „w szufladzie obok”, tylko że szuflada obok jest liczona od tej kartki.

Naprawa: pisz adres tak, jakbyś stał w folderze linku (cd projekt; ln -s plik.txt link.txt), albo daj ścieżkę bezwzględną od /. Wiszące linki w całym folderze znajdziesz tak:

find . -xtype l
./projekt/link.txt

Drugi częsty błąd: rm -rf link_do_folderu/ z ukośnikiem na końcu. Bez ukośnika usuwasz sam drogowskaz. Z ukośnikiem możesz wyczyścić zawartość folderu, na który on pokazuje. Przy symlinkach do folderów usuwaj bez ukośnika na końcu, a jak masz wątpliwości, ćwicz na maszynie wirtualnej.

✎ Zadanie

  1. W nowym folderze utwórz plik oryginal.txt z dowolnym tekstem. Zrób do niego link twardy twardy.txt i symboliczny miekki.txt.
  2. Komendą ls -li sprawdź numery i-węzłów i licznik linków. Zapisz, który link ma ten sam numer co oryginał.
  3. Usuń oryginal.txt. Sprawdź, który link działa, a który wisi. Potem napraw wiszący link, nie usuwając go.
  4. Sprawdź, ile i-węzłów jest zajętych na Twoim głównym dysku.
Pokaż rozwiązanie
mkdir ~/zadanie14 && cd ~/zadanie14
echo "Ważny tekst" > oryginal.txt
ln oryginal.txt twardy.txt
ln -s oryginal.txt miekki.txt
ls -li
983063 lrwxrwxrwx 1 eryk eryk 12 Nov  3 21:14 miekki.txt -> oryginal.txt
983062 -rw-rw-r-- 2 eryk eryk 13 Nov  3 21:14 oryginal.txt
983062 -rw-rw-r-- 2 eryk eryk 13 Nov  3 21:14 twardy.txt

Ten sam numer co oryginał ma twardy.txt, a licznik linków to 2. Teraz usuwamy:

rm oryginal.txt
cat twardy.txt
cat miekki.txt
Ważny tekst
cat: miekki.txt: No such file or directory

Twardy działa, miękki wisi. Jak naprawić wiszący link bez dotykania go? Wystarczy, żeby pod adresem oryginal.txt znowu coś było. A najsprytniej: zrobić tę nazwę twardym linkiem do ocalałej treści.

ln twardy.txt oryginal.txt
cat miekki.txt
df -i /
Ważny tekst
Filesystem       Inodes  IUsed    IFree IUse% Mounted on
/dev/vda       16777216 449746 16327470    3% /

Plik wrócił z martwych dzięki temu, że miał zapasową karteczkę. Gdyby tak działało życie, nikt by nie robił kopii zapasowych. A i-węzłów zajęte 3 procent, można spać spokojnie.

Co dalej

W ls -l zostało nam jeszcze dziesięć tajemniczych znaczków na początku każdej linijki: -rw-rw-r--. W następnej lekcji rozbieramy je do śrubki. Kto może czytać Twój plik, kto zmieniać, kto uruchamiać, i czemu sudo echo do pliku systemowego wywala „Permission denied”, chociaż masz sudo.