Gestire files e directory
I file presenti sul PC vengono normalmente salvati su un hard disk; questo può memorizzare una sequenza di byte, raggruppati in blocchi, e nessuna struttura aggiuntiva. Il sistema operativo mostra una rappresentazione strutturata di questi dati, che viene chiamata file system.Grafi ed alberi
La struttura dei file viene memorizzata come un albero (che è un particolare tipo di grafo); un grafo è in generale un insieme di nodi (o vertici) e di archi che li connettono. Si può definire matematicamente come una coppia ordinata $(V, E)$ dove $V$ è un insieme di nodi, e $E \subseteq V \times V$ sono gli archi. Un grafo viene detto albero quando non presenta cicli.
Nella terminologia degli alberi solitamente si riconosce un nodo principale, detto radice; i nodi a lui connessi tramite un arco sono detti figli; analogamente, questi altri nodi avranno degli altri figli, corrispondenti ai nodi raggiungibili in due passi dalla radice, e così via. I nodi che non hanno figli vengono detti foglie.
Si noti che la distanza dalla radice è una distanza ben definita su $V$, perché se esistesse più di un cammino che collega la radice e qualsiasi altro nodo dovremmo necessariamente avere un ciclo.
File system
Nei file system su Linux il nodo radice viene denotato
da /
; i suoi figli hanno un nome del tipo
/figlio1 /figlio2 /figlio3 ...Analogamente, queste possono avere ulteriori figli come
/figlio1/sottofiglio1
. Ogni foglia nell'albero può
corrispondere ad un file, oppure ad una directory vuota.
In questa nuova ottica, possiamo pensare al comando ls
come ad un comando che elenca i figli di un dato nodo. Similmente,
il comando tree
mostra graficamente tutto il sottoalbero
ottenuto a partire da un determinato nodo.
tree
.
Si provi ad utilizzarlo nella propria home directory.
Per interrompere un comando che si è bloccato, o richiede
troppo tempo per essere eseguito, si può usare la combinazione
di tasti CTRL+C
. Provare ad esempio a digitare
tree /
. Questo comando lista tutto l'albero dei files
presenti nel sistema.
Le directory home, dove gli utenti memorizzano i
dati, vengono create come "figli" della directory /home
,
e prendono come nome /home/mario
, /home/pippo
, ecc.,
a seconda del nome dell'utente. Dato che questa directory è di uso molto
comune, può essere sempre rimpiazzata dal simbolo ~
, come
si è visto negli esercizi precedenti.
cd
; provare ad esempio ad entrare nella
cartella ~/.ssh
dando il comando
$ cd .sshSi noti che non è necessario inserire la tilde, perché il percorso in cui spostarsi viene specificato in modo relativo (ovvero, entra nella cartella
.ssh
a partire da dove sono ora).
Files e inode
Ogni file corrisponde ad una determinata sequenza di byte, che deve essere salvata sul supporto di archiviazione (SSD, Hard disk, DVD, ecc.) Per sapere in quale punto del disco il file viene memorizzato, ad ogni filename viene associato un numero intero detto inode.
ls -i ~/.ssh
per visualizzare gli inode
relativi ai file contenuti nella cartella ~/.ssh
. Si provi a
visualizzare anche gli inode legati ad altri file, più vicini alla radice.
Possiamo definire il file come l'insieme di dati memorizzati, l'inode come l'identificatore dell'area dove questi sono memorizzati, ed il filename come un'etichetta per questo inode.
La corrispondenza fra filename e inode non è biunivoca: ad un inode possono corrispondere più filename; chiaramente, cambiare il contenuto di un file altera anche il contenuto di quello disponibile sotto un'etichetta (filename) diverso, ma che corrisponde allo stesso inode. Ad entrambi corrispondono gli stessi dati fisici sul disco. Normalmente, si dice che i due filename sono collegati; il termine utilizzato in Linux per questo collegamento è hard link.
echo
combinato con
la redirezione dell'output per creare un file con del testo nella
cartella corrente, ad esempio:
$ echo "testo di prova" > miofile.txtSi controlli l'esistenza del nuovo file con
ls
,
e si stampi il contenuto con cat
; si crei poi un hard link
a quel file con il comando
$ ln miofile.txt altrofile.txtSi controlli il contenuto di
altrofile.txt
, che dovrà essere
lo stesso di file.txt
; si provi ad aggiornare il contenuto
del file con il comando echo
. Si controlli il numero di inode
dei due filename utilizzando ls -i
.
Per eliminare un file, si può utilizzare il comando rm
.
Quest'operazione rimuove l'etichetta di un determinato inode.
Se quell'etichetta era l'unica che identificava quei file, allora
i dati non saranno più disponibili.
Ad esempio, rm miofile.txt
rimuove il filename che è stato
appena creato. Normalmente, questo rende inaccessibili i dati
precedentemente salvati, perché la maggior parte dei file è
disponibile attraverso un unico filename.
Tuttavia, nell'esempio in considerazione gli stessi dati sono identificati
anche dal file altrofile.txt
che quindi rimarrà disponibile.
Tramite il comando ls
è sempre possibile vedere quanti file puntano
un determinato inode (è il numero nella seconda della colonna dell'output
di ls -l
).
rm
sui file creati tramite
hard-link. Si può osservare che il comando rm
si
limita a scollegare un hard-link. Verificare utilizzando
ls -l
.
Ci sono altre due operazioni basilari che si possono effettuare sui
file: la copia (tramite il comando cp
) e lo spostamento
(tramite il comando mv
). La sintassi per cp
è la seguente:
$ cp sorgente destinazioneQuesti comandi sembrano simili, ma sono fondamentalmente differenti:
- Il comando
mv
è equivalente a modificare l'etichetta (o filename) data ad un certo inode, ovvero ad una determinata posizione sul disco. In particolare, questo comando è sempre ``atomico'' su Linux: può essere stato eseguito o meno, ma il sistema garantisce che non è possibile interromperlo a metà. In pratica, il suo effetto è sempre immediato. Ovviamente, questo vale solo nel caso in cui venga eseguito sullo stesso file-system, e non se si desidera spostare un file su un diverso file-system. - Il comando
cp
, invece, effettua una copia di ogni singolo byte del file sorgente nel file destinazione. Il suo costo è dunque proporzionale alla dimensione del file da copiare (un file più lungo richiederà più tempo).
cp
che permette di
copiare i file effettuando degli hard-link, invece che delle
vere copie. In questo senso, il comando diventa sostanzialmente
equivalente a ln
. Utilizzare man
per
determinare questa opzione, e provare a fare una copia di un file
di testo.
Directories
Per creare directories, è possibile utilizzare il comando
mkdir
.
test
, e al suo
interno generare almeno tre file che contengano del testo
a propria scelta. È possibile avere dettagli sull'utilizzo
di mkdir
con il comando man mkdir
.
Utilizzare il comando cd
per
spostarsi fra le cartella. Si ricordi che ..
indica la cartella superiore, e dunque per "uscire" da una
cartella si può usare il comando cd ..
I comandi mv
e cp
permettono
di spostare e copiare cartelle, oltre che file.
Ad esempio, per spostare una cartella
si può usare la sintassi
$ mv nomevecchio nomenuovo
mv
e cp
sui file
creati in precedenza dentro la cartella test
; nel caso
fossero stati eliminati, ricrearli.
Il comando cp
non permette di spostare cartelle, almeno
senza parametri aggiuntivi; questo perché lo spostamento richiede solo
di rinominare un nodo del grafo (un'operazione relativamente semplice),
mentre una copia di una directory richiede di copiare ricorsivamente anche
tutto il sottoalbero.
cp
, scoprire l'opzione necessaria
per attivare la modalità di copia ricorsiva, ed utilizzarla per copiare
la cartella test
in una di nome test2
. Controllare
che tutti i file siano stati copiati correttamente.
Come per cp
, anche il comando di rimozione rm
deve agire ricorsivamente per eliminare delle cartelle.
rm
ed utilizzare la modalità ricoriva
per eliminare la cartella test2
, ed anche la cartella
test
. Attenzione! Un uso improprio di rm
potrebbe rimuovere tutti i vostri file.
Metadati
Nel filesystem, oltre ai dati contenuto nel file stesso, vengono memorizzati anche dei metadati riguardanti alcuni attributi del file. Un esempio che è già stato incontrato è quello del nome del file (l'etichetta); altri dati che possono venire memorizzati sono ad esempio i permessi, o le date di accesso/modifica/creazione. Il tipo di dati che viene memorizzati dipende dal file-system utilizzato. Ad esempio, i primi file-system utilizzati su DOS verso la fine degli anni'80 permettevano di usare per il nome del file solo 8 caratteri, più 3 per l'estensione. Sebbene molti di voi non abbiano vissuto quel periodo, può ancora capitare di trovare del vecchio codice (magari scritto in C o in FORTRAN) in cui i file utilizzano nomi molto brevi.