Azt tapasztalom, hogy nem mindenki van teljesen tisztában azzal, hogy pontosan mi az a kemény link (hard link) és a szimbolikus link (symbolic link), ill. akadnak félreértések. Nézzük! Röviden: * Kemény link: egy második név ugyanahhoz az inode-hoz. * Szimbolikus link: egy külön fájl, amely egy másik fájl vagy könyvtár elérési útját tárolja. A különbség megértéséhez először az inode fogalmát érdemes ismerni. Linuxban leegyszerűsítve egy fájlhoz két fontos dolog tartozik, a fájlnév és az inode (egyéb jellemzők): ``` (1) fájlnév │ ▼ (2) inode │ ├── jogosultságok ├── tulajdonos ├── időbélyegek └── a fájl adatainak helye ``` A fájlnév önmagában nem maga a fájl! A könyvtárban egy bejegyzés kapcsolja össze a fájl nevét az inode-dal. - Kemény link: Kemény linket az `ln` paranccsal hozunk létre: ln eredeti.txt link.txt Most két néven érhetjük el ugyanazt a fájlt: ``` eredeti.txt ────┐ ├──► inode 12345 ──► fájl adatai link.txt ────┘ ``` Az `ls -li` paranccsal ellenőrizhetjük is. FONTOS, ez a legtöbbször félreértelmezett dolog, a kemény link NEM másolat! Ha a link.txt tartalmát megváltoztatom az eredeti.txt tartalma is megváltozik, mert valójában ugyanazt a fájlt módosítottam, csak egy másik néven keresztül. Mi történik, ha törlöm az eredetit? Ez az egyik legfontosabb különbség a két linkelési módszer között! ``` rm eredeti.txt eredeti.txt ❌ törölve link.txt ✅ továbbra is működik │ ▼ inode 12345 │ ▼ fájl adatai ``` A link.txt továbbra is használható! Az adat nem tűnik el, mert az inode-ra még mindig hivatkozik a link.txt. A fájl tényleges adatai akkor törlődnek, amikor az utolsó kemény linket is törlöd. - Szimbolikus link: A szimbolikus linket a `ln -s` paranccsal hozzuk létre: ln -s eredeti.txt szim.txt Itt már más a helyzet: ``` szim.txt │ │ tartalma: │ "eredeti.txt elérési útvonala" ▼ eredeti.txt │ ▼ inode 12345 │ ▼ fájl adatai ``` A szimbolikus linknek saját inode-ja van, ezt szintén az `ls -li` paranccsal ellenőrizheted. Tehát a szim.txt egy speciális fájl, amely azt mondja: "Keresd meg az eredeti.txt nevű fájlt". A `ls -l` kimenetében ezért jól látható: szim.txt -> eredeti.txt. Mi történik, ha törlöm az eredetit? ``` rm eredeti.txt szim.txt ───► eredeti.txt ❌ törölve ``` A szimbolikus link megmarad, de nincs többé érvényes célja, azaz megtörik. Ha megpróbálod a `cat szim.txt` parancsot, akkor hibát kapsz, mert a szimbolikus link egy már nem létező fájlra mutat. - Fájlrendszerek: Fontos különbség, hogy kemény linkkel nem tudsz egy másik fájlrendszerben lévő fájlra hivatkozni, szimbolikus linkkel viszont igen. Ez azért van, mert a kemény link közvetlenül az inode-ra hivatkozik, az inode pedig az adott fájlrendszerhez tartozik, a szimbolikus link ezzel szemben egy útvonalat tárol. Könyvtárak esetén is ez a helyzet, csak szimbolikus linket tudsz használni (nagyon speciális esetben kemény linket is). Mikor használj szimbolikus linket: * egy könyvtárra szeretnél hivatkozni; * másik fájlrendszerre szeretnél hivatkozni; * egy konfigurációs fájlt szeretnél más helyről elérhetővé tenni; * verziók között szeretnél egyszerűen váltani; * fontos, hogy egyértelműen látszódjon: ez egy link; * könnyen szeretnéd átirányítani a linket egy másik célra. Mikor használj kemény linket: * ténylegesen ugyanazt a fájlt szeretnéd két néven elérni; * fontos, hogy az egyik név törlése ne törölje az adatot; * például hatékony pillanatkép megoldást építesz. A pillanatkép létrehozása egy adott könyvtárról a legéletszerűbb felhasználása a kemény linkeknek (pl. az rsync --link-dest is így működik), példának egy egyszerű kis szkript, ami a cp parancsot használja, ami szintén tud kemény linkeket létrehozni: ``` #!/usr/bin/env bash # Szigorú hibafelelősség: álljon le hiba esetén set -euo pipefail # Használati útmutató, ha nem megfelelő a paraméterezés if [ "$#" -ne 2 ]; then echo "Használat: $0 " echo "Példa: $0 /var/www/html /backups/snapshots/html_\$(date +%Y%m%d_%H%M%S)" exit 1 fi SOURCE_DIR="$1" TARGET_DIR="$2" # 1. Ellenőrzések if [ ! -d "$SOURCE_DIR" ]; then echo "Hiba: A forráskönyvtár ($SOURCE_DIR) nem létezik!" >&2 exit 1 fi if [ -e "$TARGET_DIR" ]; then echo "Hiba: A célkönyvtár ($TARGET_DIR) már létezik!" >&2 exit 1 fi # 2. Pillanatkép létrehozása echo "Pillanatkép készítése:" echo " Forrás: $SOURCE_DIR" echo " Cél: $TARGET_DIR" # A cp -al paranccsal kemény linkeljük a fájlokat cp -al "$SOURCE_DIR" "$TARGET_DIR" echo "Pillanatkép sikeresen elkészült!" ``` A megoldás helytakarékos, az újonnan létrejött mappában lévő fájlok pontosan ugyanazokra az inode-okra mutatnak, mint a forrásban lévők. Független törlés: ha a forráskönyvtárból törölsz egy fájlt, a pillanatképben lévő fájl nem tűnik el, mivel a kemény link számlálója (link count) még nem érte el a nullát. Végére egy kis táblázat: ``` | Tulajdonság | Kemény link | Szimbolikus link | | -------------------------------- | ----------------| ------------------------- | | Parancs | `ln fájl link` | `ln -s fájl link` | | Ugyanaz az inode? | Igen | Nem | | Saját inode-ja van? | Nem | Igen | | Másolatot készít? | Nem | Nem | | Ugyanazokat az adatokat éri el? | Igen | Igen, amíg a cél létezik | | Az eredeti törlése után működik? | Igen | Nem | | Könyvtárra mutathat? | Általában nem | Igen | | Másik fájlrendszerre mutathat? | Nem | Igen | | Nem létező célra létrehozható? | Nem | Igen | | Könnyen látható, hogy link? | Nem mindig | Igen | | Gyakori használat | pillanatkép | konfigurációk, könyvtárak | ``` Berus