Linux tips and tricks/I file

Wikibooks, manuali e libri di testo liberi.
Indice del libro

In un certo senso, in Linux tutto è file. Naturalmente ci sono eccezioni numerose e importanti, ma i file restano senz'altro lo strumento principale per la rappresentazione non solo dell'informazione, ma anche di molte delle risorse, delle funzionalità e dei servizi che l'hardware mette a disposizione attraverso il sistema operativo.

Entro certi limiti, infatti, Linux gestisce gran parte dell'hardware tramite dei file. Quindi, oltre ai familiari file registrati sui dischi o altri supporti, Linux usa opportuni tipi di file per gestire comunicazioni fra processi (i socket e le pipe, anonime o meno), raccolte di file (le ben note directory, file come gli altri, ma che servono solo a contenere elenchi di file), dispositivi di ingresso e uscita di vario tipo (i device, che possono essere a blocchi oppure a caratteri).

Pertanto, sapere manipolare i file oltre le possibilità (e la comodità) dell'interfaccia grafica preferita è di fondamentale importanza, non solo per l'amministratore di sistema, ma anche per l'utente casalingo che volesse provare il brivido di impostare i tag ID3 di migliaia di file MP3 con un singolo, anche se complesso, comando testuale.

File regolari e file speciali[modifica]

Ci sono molti modi per definire un file. Qui proveremo a considerarlo semplicemente come una sequenza di byte, non necessariamente statica. Potremo così considerare come file anche un flusso, continuo o meno, di dati che arrivano da Internet, o vengono inviati a una scheda audio, o scambiati, attraverso delle code, da due programmi in esecuzione. È in parte una forzatura, ma in molti casi si rivela utile, e basterà fare qualche precisazione nei pochi casi particolari in cui la forzatura è davvero eccessiva.

Un file regolare è una sequenza di byte registrata su memoria di massa (dischi, nastri, pen drive, memory card o altro). Il caso più elementare sono i file di testo, in cui, grosso modo, ogni singolo byte corrisponde ad una lettera dell'alfabeto inglese, oltre ai segni di interpunzione e alcuni altri simboli di uso frequente in occidente. Presentare su un terminale o in un editor di testo in modalità grafica un file di testo è dunque molto semplice.

Altri file invece possono essere interpretati solo da programmi o funzioni di libreria che implementano opportuni algoritmi. Si pensi ai file compressi nei vari formati, o ai file Word, ai file JPEG, e ai tanti altri tipi di file che servono a memorizzare informazioni complesse sempre secondo una opportuna sequenza di byte: la differenza sta nella logica con cui l'informazione viene codificata, ma sempre sequenze di byte sono.

In questo contesto non ci interessano i formati, quanto le caratteristiche comuni a tutti i file, nel senso che abbiamo dato all'espressione. Prima però è utile distinguere in dettaglio i vari tipi di file normalmente gestiti da tutti i file system esistenti per Linux.

Nel seguito si fa riferimento al classico comando ls, e in particolare a ls -l, che mostra praticamente tutte le informazioni discusse.

Directory[modifica]

Una directory è semplicemente un file regolare il cui contenuto è un elenco di file. Questi possono essere a loro volta directory, o qualsiasi altro tipo di file.

Le directory aggiungono al file system potenzialità enormi nell'organizzare l'informazione, e per la loro importanza vengono normalmente gestiti in modo diverso. Ad esempio, il comando cat, che serve a inviare sullo standard output il contenuto di un file, non può essere usato con una directory. Per visualizzare il contenuto di una directory occorre un'opportuna chiamata al sistema operativo, oppure un comando come ls che la effettui per conto nostro.

Proprio con ls -l è possibile distinguere le directory, fra i file contenuti nella directory corrente, dal carattere d in prima colonna (i file regolari hanno invece un - in prima posizione).

Link[modifica]

A essere precisi, una directory contiene un elenco di coppie (nome file, numero i-node). Gli i-node (pronuncia eye-node) sono in un certo senso posizioni fissate su disco in cui sono descritti i file. Ogni file corrisponde a un i-node e viceversa. Nell'i-node è anche registrata la posizione iniziale del file.

Fatta questa precisazione, possiamo dire che un link a un file è nome diverso per lo stesso file. Questo può essere utile in moltissimi casi, e si può realizzare in due modi completamente diversi: con gli hard link e con i soft link (detti anche link simbolici).

L' hard link ciccio al file pippo, in una directory, è registrato come una coppia (ciccio, i-node di pippo): ciccio e pippo hanno lo stesso i-node, e quindi sono pressoché indistinguibili.

Il link simbolico pluto al file pippo, invece, ha un proprio i-node, diverso da quello di pippo, e nella directory che lo contiene è rappresentato da una coppia (pluto, i-node di pluto).

La differenza è sottile, ma in questo contesto interessa soprattutto il fatto che, con ls -l, un link simbolico è evidenziato da una l in prima posizione, come sotto:

$ ls -l /etc/bashrc
lrwxrwxrwx 1 root root 11 2005-02-18 16:02 /etc/bashrc -> bash.bashrc

Lo stesso comando non consentirebbe di distinguere un hard link.

Pipe[modifica]

Molte componenti del sistema, ma anche programmi applicativi, utilizzano le cosiddette named pipe per comunicare fra di loro. Si tratta di tipiche strutture FIFO (First In, First Out), dette in italiano anche code, in cui un programma può scrivere qualcosa che, all'altra estremità, può essere prelevato da un altro programma.

Quando si usa l'operatore '|', appunto detto pipe, per combinare fra loro l'output e l'input di vari programmi, non si fa altro che creare delle pipe temporanee di cui l'utente non ha consapevolezza immediata. Queste pipe vengono spesso create in /tmp, e si possono individuare con ls -l per la lettera p in prima posizione. Una directory in cui spesso si trovano pipe non temporanee è /var, come in questo esempio:

$ ls -l /var/spool/postfix/public/
prw--w--w- 1 postfix postdrop 0 2006-08-08 17:40 pickup
prw--w--w- 1 postfix postdrop 0 2006-08-08 17:40 qmgr

Socket[modifica]

Si tratta di un altro meccanismo per la comunicazione fra processi, anche questo usato sia da componenti del sistema operativo, sia da programmi applicativi, tipicamente di tipo server. I socket si distinguono nell'output di ls -l da una s in prima posizione, come nell'esempio seguente:

$ ls -l /var/spool/postfix/public/
srw-rw-rw- 1 postfix postdrop 0 2006-08-04 17:25 cleanup
srw-rw-rw- 1 postfix postdrop 0 2006-08-04 17:25 flush
srw-rw-rw- 1 postfix postdrop 0 2006-08-04 17:25 showq

Per inciso, postfix è un server di posta elettronica che evidentemente, per funzionare, usa sia delle pipe, sia dei socket. Spesso anche i server di database usano i socket per l'accesso in locale, mentre usano connessioni TCP/IP per l'accesso via rete.

Dispositivi di I/O[modifica]

Infine, tutti i dispositivi di I/O sono rappresentati da file particolari. Ce ne sono di due tipi:

  • a blocchi, tipicamente ad accesso bufferizzato e casuale
  • a carattere, tipicamente ad accesso non bufferizzato e sequenziale

In alcuni casi, ad uno stesso dispositivo fisico corrispondono due file per dispositivi: uno a blocchi e uno a carattere. In questo modo è possibile accedere in due modi diversi allo stesso dispositivo fisico, a seconda delle esigenze.

I dispositivi a blocchi si distinguono per una b iniziale nell'output di ls -l, mentre quelli a carattere si distinguono per una c. Tipicamente, i dischi sono dispositivi a blocchi, mentre sono a carattere terminali, schede video, schede audio, mouse, tastiere e molto altro. Esempi ovvi:

$ ls -l /dev/hdb*|head -5
brw-rw---- 1 root disk 3, 64 2006-08-04 17:24 /dev/hdb
brw-rw---- 1 root disk 3, 65 2006-08-04 17:24 /dev/hdb1
brw-rw---- 1 root disk 3, 74 2006-08-04 17:24 /dev/hdb10
brw-rw---- 1 root disk 3, 75 2006-08-04 17:24 /dev/hdb11
brw-rw---- 1 root disk 3, 76 2006-08-04 17:24 /dev/hdb12
$ ls -l /dev/input/
crw-rw---- 1 root root 13,  64 2006-08-04 17:24 event0
crw-rw---- 1 root root 13,  65 2006-08-04 17:24 event1
crw-rw---- 1 root root 13,  66 2006-08-04 17:24 event2
crw-rw---- 1 root root 13,  63 2006-08-04 17:24 mice
crw-rw---- 1 root root 13,  32 2006-08-04 17:24 mouse0

Permessi[modifica]

A parte il tipo, i file hanno molte caratteristiche importanti. Certamente quelle più importanti sono legate ai permessi: si tratta in pratica di stabilire, per un dato file, chi può fare cosa con quel file.

La maggior parte dei file system esistenti prevede degli attori e delle azioni. Combinando fra loro questi due elementi, è possibile specificare in modo piuttosto preciso chi può fare cosa.

Attori: utente, gruppo e altri[modifica]

Ogni file, di qualsiasi tipo esso sia, ha un utente proprietario e un gruppo proprietario. Più sinteticamente, si parla di solito di utente e gruppo del file, essendo sottintesa la proprietà.

Ogni file, inoltre, appartiene implicitamente agli altri (others). Si crea così una specie di gerarchia, che vede l'utente proprietario al vertice e gli altri alla base.

Azioni: lettura, scrittura, esecuzione[modifica]

Ogni attore può essere autorizzato o meno a fare sostanzialmente solo tre cose con un file: leggerlo, modificarlo o eseguirlo. L'esecuzione ha un senso diverso nel caso delle directory: significa poter esaminare il suo contenuto. È sottilmente diversa dalla lettura, che non basta a questo scopo.

Permessi: varie combinazioni di attori e azioni[modifica]

I permessi di un file sono l'insieme delle azioni che ciascuno dei tre attori può effettuare su quel file. Prima di vedere come si assegnano i permessi ad un file, vediamo come si riconoscono col comando ls -l:

$ ls -l /etc/bashrc
lrwxrwxrwx 1 root root 11 2005-02-18 16:02 /etc/bashrc -> bash.bashrc

I permessi di questo file sono le tre terne rwx dopo la l. Ogni terna specifica le azioni permesse ad un attore: da sinistra, l'utente proprietario, il gruppo proprietario e infine tutti gli altri utenti e gruppi.

Per maggiore chiarezza, mettiamo in evidenza i permessi relativi ai vari attori, cominciando dall'utente proprietario:

lrwxrwxrwx 1 ...

per passare al gruppo proprietario

lrwxrwxrwx 1 ...

per finire con tutti gli altri

lrwxrwxrwx 1 ...

Anche il significato delle lettere è molto semplice:

r
l'attore può leggere il contenuto del file
w
l'attore può modificare il file
x
l'attore può eseguire il file o esaminare il contenuto della directory

Altre caratteristiche[modifica]

Ad ogni file sono normalmente associate molte altre informazioni, fra cui:

  • la data dell'ultimo accesso
  • la data dell'ultima modifica
  • la data dell'ultimo cambiamento di stato
  • le dimensioni del file, in byte
  • il numero di hard link (in pratica, il numero di file che condividono lo stesso i-node)
  • gli attributi (trattati a parte)
  • l'i-node
  • il numero di blocchi utilizzati (tipicamente, un blocco è costituito da 512 byte contigui su disco)

La maggior parte di queste informazioni, e molte altre, sono accessibili con i comandi stat ed lstat, il cui output è configurabile in modo molto flessibile.