Salta al contenuto principale

ln: crea collegamenti tra file e cartelle

Inviato da tuxsa il

ln crea dei collegamenti: nomi aggiuntivi o scorciatoie che puntano a un file o a una cartella già esistenti, senza duplicarne il contenuto. Serve a rendere raggiungibile la stessa cosa da più posti, a dare un nome comodo a un percorso lungo e a gestire configurazioni e versioni di un sito.

Cos'è

ln è l'abbreviazione di link, "collegamento". Fa parte del pacchetto GNU coreutils ed è un eseguibile (/usr/bin/ln), presente su qualsiasi distribuzione GNU/Linux.

Esistono due tipi di collegamento, molto diversi tra loro, e capire la differenza è il cuore dell'argomento.

Prima di cominciare: nomi, inode e due tipi di collegamento

In un file system Linux il contenuto di un file e il suo nome sono cose separate. Il contenuto (con permessi, proprietario, date) sta in una struttura chiamata inode, identificata da un numero. Il nome è solo una voce in una cartella che dice "questo nome corrisponde a quell'inode". Lo vedi con ls -i.

  • Un collegamento fisico (hard link) è un altro nome per lo stesso inode. I due nomi sono perfettamente equivalenti: non esiste un "originale" e una "copia". I dati si cancellano solo quando sparisce l'ultimo nome. Il numero di nomi si legge nella seconda colonna di ls -l.
  • Un collegamento simbolico (symlink o soft link) è un piccolo file speciale che contiene un percorso, come un'indicazione stradale. È simile ai collegamenti di Windows o agli alias di macOS, ma il sistema lo segue in modo trasparente. Se il file di destinazione viene spostato o cancellato, il collegamento resta, ma non porta più da nessuna parte.
 Collegamento fisicoCollegamento simbolico
Comandoln origine nomeln -s origine nome
Cos'èUn altro nome per lo stesso inodeUn file che contiene un percorso
Se cancelli l'originaleIl contenuto resta accessibile dall'altro nomeIl collegamento si "spezza" (dangling)
Può collegare cartelleNoSì
Può attraversare dischi diversiNo, solo nello stesso file systemSì
Può puntare a qualcosa che non esisteNoSì
Come si riconosce in ls -lNumero di collegamenti maggiore di 1Primo carattere l e freccia ->

Nella pratica quotidiana si usano quasi sempre i collegamenti simbolici.

Cosa fa

Crea un nuovo nome che rimanda a un file o a una cartella già esistenti. Non copia i dati e non occupa spazio significativo: un collegamento fisico non ne occupa affatto, uno simbolico solo lo spazio del percorso che contiene. In caso di successo non stampa nulla.

Come si usa

$ ln [opzioni] destinazione nome_del_collegamento
$ ln -s destinazione nome_del_collegamento

Attenzione all'ordine, che è la causa di errore più frequente: prima si scrive ciò a cui il collegamento punta, poi il nome del collegamento che si crea. Come in cp, si scrive prima l'esistente e poi il nuovo.

Esempio 1: un collegamento fisico

$ ln appunti.txt appunti_link.txt
$ ls -li appunti*
2631845 -rw-r--r-- 2 enzo enzo 812 ott  2 10:15 appunti.txt
2631845 -rw-r--r-- 2 enzo enzo 812 ott  2 10:15 appunti_link.txt

Con -i ls mostra il numero di inode (la prima colonna): è lo stesso per i due nomi, perché sono due nomi dello stesso file. Il 2 nella terza colonna è il numero di nomi che il file ha.

Esempio 2: cosa succede se si cancella un nome

$ echo "prima riga" > originale.txt
$ ln originale.txt copia_fisica.txt
$ echo "seconda riga" >> copia_fisica.txt
$ cat originale.txt
prima riga
seconda riga
$ rm originale.txt
$ cat copia_fisica.txt
prima riga
seconda riga
$ ls -l copia_fisica.txt
-rw-r--r-- 1 enzo enzo 24 ott 14 07:35 copia_fisica.txt

Le modifiche fatte da un nome si vedono dall'altro, e dopo aver eliminato uno dei due nomi il contenuto è ancora lì: il numero di collegamenti è tornato a 1. È il motivo per cui rm in realtà "toglie un nome" e il file sparisce davvero solo quando non ne ha più nessuno.

Esempio 3: un collegamento simbolico a una cartella

$ ln -s /var/www/html ~/sito
$ ls -l ~/sito
lrwxrwxrwx 1 enzo enzo 13 ott  2 10:20 /home/enzo/sito -> /var/www/html
$ cd ~/sito
$ pwd
/home/enzo/sito
$ pwd -P
/var/www/html

Ora ~/sito è una scorciatoia a /var/www/html. Il primo carattere l e la freccia -> mostrano che è un collegamento simbolico, e il numero 13 è la lunghezza del percorso che contiene. L'ultimo esempio richiama l'articolo su pwd: pwd mostra il percorso "logico", pwd -P quello fisico.

Esempio 4: un collegamento simbolico a un file

$ ln -s /etc/nginx/nginx.conf ~/nginx.conf
$ cat ~/nginx.conf

Leggere il collegamento equivale a leggere il file di destinazione. Se omettessi il nome del collegamento, ln -s /var/log/syslog creerebbe un collegamento chiamato syslog nella cartella corrente.

Esempio 5: un collegamento "spezzato"

$ echo "ciao" > dati.txt
$ ln -s dati.txt scorciatoia.txt
$ cat scorciatoia.txt
ciao
$ rm dati.txt
$ cat scorciatoia.txt
cat: scorciatoia.txt: File o directory non esistente
$ ls -l scorciatoia.txt
lrwxrwxrwx 1 enzo enzo 8 ott 14 07:40 scorciatoia.txt -> dati.txt

Il collegamento esiste ancora, ma punta a qualcosa che non c'è più. Nei terminali a colori compare di solito in rosso. Per trovare tutti i collegamenti spezzati in una cartella:

$ find . -xtype l

Con -xtype l find cerca i collegamenti simbolici che non portano a nulla. Prima di eliminarli con -delete, controlla l'elenco.

Esempio 6: percorsi relativi, la trappola più comune

Un collegamento simbolico può contenere un percorso assoluto (che inizia con /) o relativo. Un percorso relativo viene interpretato rispetto alla cartella in cui si trova il collegamento, non rispetto a dove ti trovi quando lo usi:

$ cd ~/progetto
$ ln -s ../condivisi/config.ini config.ini
$ cat config.ini

Qui ../condivisi/config.ini è "la cartella condivisi accanto a progetto". Funziona perché il collegamento è dentro ~/progetto. L'errore tipico è invece lanciare il comando da un'altra cartella:

$ cd ~
$ ln -s condivisi/config.ini progetto/config.ini
$ cat progetto/config.ini
cat: progetto/config.ini: File o directory non esistente

Il collegamento è stato creato dentro progetto, ma contiene il percorso condivisi/config.ini, che da lì non esiste. Due rimedi: usare un percorso assoluto, oppure lasciar calcolare il percorso relativo a ln con l'opzione -r:

$ ln -sr condivisi/config.ini progetto/config.ini
$ ls -l progetto/config.ini
lrwxrwxrwx 1 enzo enzo 23 ott 14 07:42 progetto/config.ini -> ../condivisi/config.ini

Con -r (relative) ln scrive nel collegamento il percorso relativo corretto, partendo da dove il collegamento si trova.

Esempio 7: sapere dove punta un collegamento

$ readlink ~/sito
/var/www/html
$ readlink -f progetto/config.ini
/home/enzo/condivisi/config.ini

Il comando readlink stampa il percorso contenuto nel collegamento; con -f segue tutti i passaggi e restituisce il percorso assoluto finale. Esiste anche realpath, che fa lo stesso.

Esempio 8: attivare un sito in nginx

Un uso reale molto comune è nelle configurazioni di nginx su Debian e Ubuntu, dove i siti disponibili stanno in una cartella e quelli attivi sono semplici collegamenti:

$ sudo ln -s /etc/nginx/sites-available/miosito.conf /etc/nginx/sites-enabled/miosito.conf
$ sudo nginx -t && sudo systemctl reload nginx

Per disattivare il sito basta eliminare il collegamento, senza toccare il file di configurazione:

$ sudo rm /etc/nginx/sites-enabled/miosito.conf

Con nginx -t si controlla la configurazione prima di ricaricare il servizio. Lo stesso schema (sites-available e sites-enabled) vale per Apache.

Esempio 9: sostituire un collegamento esistente

Se il nome del collegamento esiste già, ln fallisce. Con -f (force) lo sostituisce. Per i collegamenti che puntano a cartelle serve anche -n (no-dereference):

$ ln -sfn releases/2026-10-14 current
$ ls -l current
lrwxrwxrwx 1 enzo enzo 19 ott 14 07:45 current -> releases/2026-10-14

Senza -n, se current è già un collegamento a una cartella, ln lo seguirebbe e creerebbe il nuovo collegamento dentro quella cartella, invece di sostituire current. Questo schema serve a gestire le versioni di un sito: current punta sempre alla versione attiva e il rollback si fa ripuntando il collegamento alla versione precedente.

Il passaggio con -f elimina e ricrea il collegamento in due momenti, e per un istante current non esiste. Se serve che la sostituzione sia istantanea, si crea un collegamento temporaneo e lo si rinomina sopra quello vecchio:

$ ln -s releases/2026-10-14 current.tmp
$ mv -Tf current.tmp current

Il rinomina è un'operazione atomica: chi legge current trova sempre o il vecchio o il nuovo.

Esempio 10: più collegamenti insieme in una cartella

$ mkdir ~/bin
$ ln -s /usr/bin/python3 ~/bin/python
$ ln -s /opt/strumenti/a.sh /opt/strumenti/b.sh ~/bin/
$ ls -l ~/bin

Se l'ultimo argomento è una cartella esistente, ln crea al suo interno un collegamento per ciascun file indicato, con lo stesso nome dell'originale. È un modo per rendere disponibili comandi nel PATH, se ~/bin ne fa parte.

Esempio 11: trovare i nomi dello stesso file

$ find ~ -samefile appunti.txt
/home/enzo/appunti.txt
/home/enzo/appunti_link.txt

Con -samefile find trova tutti i nomi che puntano allo stesso inode. Utile quando ls -l mostra più di un collegamento e vuoi sapere dove sono gli altri nomi. Con -inum si cerca invece per numero di inode.

Esempio 12: eliminare un collegamento

$ rm sito
$ unlink sito

Si elimina come qualsiasi file. Il comando rm o unlink toglie il collegamento, non la cartella a cui punta. Importante: scrivi il nome senza barra finale.

Esempio 13: uso negli script

Un piccolo script di pubblicazione di un sito per versioni, con il collegamento current aggiornato in modo atomico:

#!/bin/bash
BASE="/var/www/miosito"
VERSIONE="$BASE/releases/$(date +%F_%H%M)"

mkdir -p "$VERSIONE"
cp -a "$HOME/build/." "$VERSIONE/"

ln -s "$VERSIONE" "$BASE/current.tmp"
mv -Tf "$BASE/current.tmp" "$BASE/current"

echo "Sito ora su: $(readlink -f "$BASE/current")"

Ogni pubblicazione crea una cartella nuova in releases e sposta current su di essa. Le versioni precedenti restano disponibili per tornare indietro.

Opzioni utili

  • -s: crea un collegamento simbolico (senza, un collegamento fisico).
  • -r: con -s, scrive nel collegamento il percorso relativo calcolato automaticamente.
  • -f: sostituisce un collegamento o un file già esistente con quel nome.
  • -n: se il nome indicato è un collegamento a una cartella, lo tratta come un file normale invece di seguirlo.
  • -i: chiede conferma prima di sostituire.
  • -v: mostra cosa viene creato.
  • -T: considera il nome del collegamento sempre un nome di file, mai una cartella di destinazione.
  • -t cartella: indica la cartella in cui creare i collegamenti, e permette di scrivere prima i file.

Attenzione a

  • L'ordine degli argomenti: ln -s destinazione nome, non il contrario. Se li scambi, ottieni un collegamento al posto sbagliato o l'errore File esistente. Se non sai se l'hai fatto giusto, controlla con ls -l: dopo la freccia -> deve esserci la destinazione.
  • I percorsi relativi sono relativi al collegamento: se il collegamento "non funziona", spesso è questo. Usa un percorso assoluto, oppure ln -sr. E ricorda che spostare un collegamento relativo in un'altra cartella può spezzarlo.
  • I collegamenti spezzati: se sposti o rinomini la destinazione, i collegamenti simbolici non vengono aggiornati. Controlla con find . -xtype l.
  • I collegamenti fisici hanno limiti: non attraversano file system diversi (Invalid cross-device link, in italiano Collegamento non valido tra dispositivi), non possono puntare a cartelle e non sono possibili con tutti i file system. In quei casi usa un collegamento simbolico.
  • Alcuni programmi spezzano i collegamenti fisici: molti editor di testo salvano un file scrivendone uno nuovo e rinominandolo sopra al vecchio, e anche sed -i funziona così. Il file modificato diventa un inode nuovo e il vecchio nome resta con il contenuto di prima: i due nomi non sono più lo stesso file. Con i collegamenti simbolici il problema non c'è.
  • Eliminare un collegamento a una cartella: rm sito toglie solo il collegamento. Ma rm -rf sito/*, con la barra e l'asterisco, cancella il contenuto della cartella di destinazione, perché la shell espande l'asterisco nei file che stanno dentro. Con un collegamento, scrivi sempre il nome senza barra finale e senza asterisco.
  • I permessi: un collegamento simbolico compare sempre come lrwxrwxrwx, ma quei permessi non contano: valgono quelli della destinazione. Anche chmod su un collegamento agisce sulla destinazione, e chown fa lo stesso a meno di usare -h. Per un collegamento fisico, i permessi sono quelli del file, quindi condivisi da tutti i nomi.
  • Cicli: un collegamento a una cartella che contiene sé stesso (per esempio ln -s .. su) può mandare in loop programmi che scorrono le cartelle in modo ricorsivo. find non segue i collegamenti simbolici a meno che tu non usi -L.
  • Gli strumenti di copia: copiando o archiviando, un collegamento può essere copiato come collegamento oppure sostituito dal file a cui punta, secondo lo strumento e le opzioni. tar conserva di norma i collegamenti, simbolici e fisici. Con cp, -a li conserva, e -L li segue copiando i contenuti.
  • Lo spazio su disco: du conta un file con più collegamenti fisici una volta sola, quindi non stupirti se la somma non coincide con quanto vedi in ls.
  • Windows e dischi esterni: su file system come FAT ed exFAT, tipici di chiavette e dischi esterni, i collegamenti simbolici e fisici non sono supportati. Il comando ln dà errore e i programmi di copia possono sostituirli con copie dei file.

Riepilogo

ComandoCosa fa
ln file nomeCrea un collegamento fisico (altro nome dello stesso file)
ln -s destinazione nomeCrea un collegamento simbolico
ln -sr destinazione nomeCrea un collegamento simbolico con percorso relativo corretto
ln -sfn nuova currentSostituisce un collegamento a una cartella
ln -s file1 file2 cartella/Crea più collegamenti dentro una cartella
ls -l / ls -liMostra destinazione, numero di collegamenti e inode
readlink -f nomeMostra il percorso assoluto a cui punta
find . -xtype lTrova i collegamenti simbolici spezzati
find / -samefile fileTrova tutti i nomi dello stesso file
rm nome / unlink nomeElimina il collegamento (senza barra finale)