Hard link e Soft link
Hard Link
Nei filesystem unix, come ad esempio EXT, UFS o ZFS, è possibile creare un link ad un file, cioè dare la possibilità di accedere ad un dato file usando due nomi diversi.
Ad esempio:
$ echo 'il mio contenuto' > file1.txt
$ ln file1.txt file2.txt
$ ls
file1.txt file2.txt
$ cat file2.txt
il mio contenuto
$ echo 'aggiungo al file' >> file1.txt
$ cat file2.txt
il mio contenuto
aggiungo al file
Come si vede dall'esempio, abbiamo creato il file file1.txt, poi abbiamo creato un link al file con ln, infatti aggiungendo dati al file file1.txt questi dati li troviamo anche in file2.txt.
E' importante notare che file1.txt e file2.txt non sono due file diversi, sono semplicemente due modi diversi di chiamare lo stesso file.
Posso avere una immediata dimostrazione di quanto appena detto usando il comando ls -i
che mostra gli inode a cui fanno riferimento i file (per chi non ha confidenza con il termine inode, diciamo che è un puntatore allo spazio fisico dove risiedono i dati di un file).
$ ls -i
13373083 file1.txt 13373083 file2.txt
Vediamo che entrambi i file puntano allo stesso inode, quindi in pratica condividono il contenuto.
In questo esempio ho creato il link nella stessa directory ma posso crearlo anche in altre directory, purché facciano parte dello stesso filesystem.
Soft link
E' possibile creare hard link solo di file, non è possibile crearne di directory, inoltre, come abbiamo già detto, non è possibile creare un link di un file in un filesystem diverso (ad esempio se ho 2 hard disk montati come /mnt/a e /mnt/b non posso creare in /mnt/b un link ad un file che risiede in /mnt/a.
Per fortuna i filesystem Unix offrono una possibile alternativa che non soffre di queste limitazioni: i soft link (detti anche symbolic link o più in breve symlink). Posso creare un soft link usando sempre il comando ln ma specificando lo switch -s. Ad esempio:
ln -s /etc/hosts ./hosts
crea un soft link del file /etc/hosts nella directory corrente. Oppure
ln -s /etc ./lamiaetc
crea un soflink chiamato lamiaetc che punta a /etc nella directory corrente.
Attenzione però: tra hard link e soft link ci sono alcune sottili ma importanti differenze!
Cancellazione del file originale
se creo un hard link di un file e cancello (con rm) il file originale, l'hard link mi resta e continua a contenere tutti i dati. Se invece rimuovo il file originale di un soft link, mi resta solo il link che rimane "orfano", ossia non punta più a un file valido e quindi non conterrà più dati.
Esempio:
$ echo "Dati" > file1.txt
$ ln file1.txt hardlink.txt
$ ln -s file1.txt softlink.txt
$ rm file1.txt
$ cat hardlink.txt
Dati
$ cat softlink.txt
cat: softlink.txt: File o directory non esistente
Spostamento/rinomina del file originale
Anche in questo caso vale quanto detto per la cancellazione: l'hard link rimane intatto mentre invece il soft link "perde" il file a cui puntava.
$ echo "Dati" > file1.txt
$ ln file1.txt hardlink.txt
$ ln -s file1.txt softlink.txt
$ mv file1.txt file-newname.txt
$ cat hardlink.txt
Dati
$ cat softlink.txt
cat: softlink.txt: File o directory non esistente
Link e permessi
Un fatto da tenere in considerazione riguardo ai link è che gli hard link condividano i permessi di accesso, nel senso che se ho un file con due hard link e cambio i diritti di accesso ad uno dei due, anche l'altro avrà i medesimi diritti di accesso. Vediamo un esempio pratico:
$ ls -l
-rw-rw-r-- 2 maurizio maurizio 34 nov 15 10:17 file1.txt
-rw-rw-r-- 2 maurizio maurizio 34 nov 15 10:17 file2.txt
$ chmod o-r file1.txt
$ ls -l
-rw-rw---- 2 maurizio maurizio 34 nov 15 10:17 file1.txt
-rw-rw---- 2 maurizio maurizio 34 nov 15 10:17 file2.txt
In pratica i permessi di accesso seguono il contenuto del file e non il modo in cui lo chiamo.
Per i soft link invece la situazione è un po' più complicata perché il loro comportamento può cambiare da una implementazione ad un'altra del sistema operativo, o addirittura può essere configurata in modo diverso. Di solito su i sistemi Linux i soft link hanno sempre permessi 777 (lettura, scrittura e esecuzione per tutti) ma in realtà valgono i permessi assegnati al file destinazione, quindi le operazioni di lettura o scrittura tentate su un soft link riescono se le permission del file di destinazione le consentono.
Nel seguente esempio abbiamo un file test.txt con accesso in scrittura consentito solo a root. Il soft link softlink.txt punta a quel file e nonostante questo abbia permessi 777 non posso comunque scrivere su quel file usando il mio utente:
$ ls -l
lrwxrwxrwx 1 maurizio maurizio 8 nov 19 13:07 softlink.txt -> test.txt
-rw-rw-r-- 1 root root 0 nov 19 13:07 test.txt
$ echo "aggiungi" >> softlink.txt
bash: softlink.txt: Permesso negato
Identificazione dei link
Identificare un link è facile, basta usare lo switch -l del comando ls per visualizzare i dati di dettaglio sui file:
$ ls -l
-rw-rw-r-- 2 maurizio maurizio 34 nov 15 10:17 file1.txt
-rw-rw-r-- 2 maurizio maurizio 34 nov 15 10:17 file2.txt
lrwxrwxrwx 1 maurizio maurizio 10 nov 15 10:48 hosts -> /etc/hosts
In questo esempio vediamo che il file hosts presente in questa directory in realtà è un soft link (lo vediamo dalla l all'inizio della stringa dei permessi) che in realtà punta a /etc/hosts.
Vediamo anche che i file file1.txt e file2.txt hanno ognuno almeno un altro nome infatti il numero 2 tra la stringa dei permessi e l'owner del file indica il numero di hard link del file. Normalmente un file ha 1 che significa che nel filesystem quel file è raggiungibile con un solo nome.
Come sappiamo visto che questi file sono stati generati in un esempio qui sopra, in realtà file1.txt e file2.txt sono hard links dello stesso contenuto.
Possiamo verificarlo facilemente usando ls -i
:
$ ls -i
13373083 file1.txt 13373083 file2.txt 13432360 hosts
Infatti i due file hanno lo stesso identificativo inode, quindi sono a tutti gli effetti lo stesso file.