Comando file in Linux: formato, tipo MIME e codifica

Il comando file identifica il tipo di un file esaminando metadati, sequenze di byte e caratteristiche del testo. Può riconoscere un formato anche quando l’estensione manca o è sbagliata; il risultato è una classificazione basata su regole, non una garanzia di integrità o sicurezza.

Questa guida riguarda file e la libreria libmagic usati su Linux e altri sistemi Unix. Spiega output leggibile, tipi MIME, codifiche, collegamenti simbolici, compressione e uso negli script. Disponibilità delle opzioni e precisione dipendono dalla versione e dal database magic, che contiene le regole di riconoscimento.

Che cos'è il comando file?

file esamina i percorsi indicati e stampa una descrizione per ciascuno. Per una prima prova completa, scegli una directory scrivibile in cui file-demo non esista ancora. La sequenza seguente crea due file di testo e un file vuoto, senza usare documenti personali; && interrompe i passaggi successivi se un comando fallisce.

mkdir file-demo &&
cd ./file-demo &&
printf '%s\n' 'Ciao dal file di prova.' > README.md &&
printf '%s\n' 'Caffè e città' > utf8.txt &&
: > empty.bin &&
file -- README.md utf8.txt empty.bin

Con file 5.47 e il relativo database, per questi contenuti ci si aspetta una descrizione simile alla seguente. La formattazione può variare con la versione, il database e l’ambiente; verifica soprattutto la distinzione tra testo ASCII, testo UTF-8 e file vuoto.

README.md: ASCII text
utf8.txt:  Unicode text, UTF-8 text
empty.bin: empty

file legge senza riscrivere il contenuto, ma richiede accesso al percorso e può aggiornare il tempo di ultimo accesso secondo il file system e le sue opzioni. Dopo la prova ti trovi dentro file-demo. Gli altri nomi e percorsi della guida sono esempi: devono esistere, oppure vanno sostituiti con i tuoi file.

Come file riconosce un formato

Normalmente file applica queste tre famiglie di controlli nell’ordine indicato e stampa il primo risultato utile. -k permette invece di continuare a cercare altre corrispondenze nelle regole magic.

  1. Controllo del file system: Controlla tipi come directory, collegamenti simbolici, socket, FIFO e file vuoti tramite i metadati.
  2. Controllo magic: Confronta schemi unici di byte in posizioni specifiche di un file con il database magic.
  3. Controllo del testo e della lingua: Esamina la codifica dei caratteri e le caratteristiche del contenuto per stimare il formato del testo o la lingua in cui è stato scritto.

Formati con firme riconoscibili, come PNG, JPEG, PDF ed ELF, possono essere identificati senza affidarsi al nome. ELF significa Executable and Linkable Format, un formato usato anche per eseguibili e librerie Linux. Dati troppo brevi o non riconosciuti possono ricevere semplicemente la descrizione data.

Sintassi di base e utilizzo

file [option] file...

È possibile controllare non solo un singolo file ma anche più percorsi contemporaneamente.

file report.pdf
file image.png archive.tar.gz script.sh
file /etc /dev/null /usr/bin/env

Racchiudi tra virgolette i percorsi con spazi o caratteri speciali. Prima di un nome che inizia con un trattino usa --, che termina le opzioni.

file "annual report.pdf"
file -- -sample.bin

È possibile controllare la versione installata e le opzioni supportate con il seguente comando.

file --version
file --help
man file

Confrontare le estensioni e il formato effettivo del file

Controlla il formato anche senza un'estensione

I file eseguibili Linux o gli script di comando spesso non hanno estensioni. file può controllare il formato ispezionando il contenuto invece del nome.

file /usr/bin/bash
file /usr/bin/python3
file ./run-backup

La prima riga di uno script, detta shebang, può indicare l’interprete e influire sulla descrizione. Per un eseguibile Linux, per esempio file /usr/bin/ls, il risultato può indicare ELF, architettura e collegamento dinamico. Questi dettagli dipendono dal file reale; gli eseguibili Windows possono invece essere riconosciuti come PE e non vanno confusi con ELF.

Controlla i file con estensioni errate

Questo è utile anche quando l'estensione di un file scaricato o ricevuto non corrisponde al contenuto reale.

file download.dat
file attachment.bin

file non rinomina il file. Se un’immagine PNG è stata chiamata download.dat, la firma può comunque farla riconoscere come PNG. Prima di cambiare l’estensione verifica che il programma destinato ad aprirla ne supporti davvero il formato.

Interpretazione dei risultati comuni

Espressioni rappresentative Significato
directory È una directory, non un file regolare.
symbolic link to ... È un collegamento simbolico che punta a un altro percorso.
empty È un file regolare vuoto con una dimensione di 0 byte.
ASCII text È principalmente testo costituito da caratteri stampabili nell'intervallo ASCII.
Unicode text, UTF-8 È stato determinato che si tratta di testo Unicode codificato in UTF-8.
ELF ... executable È un file eseguibile in formato ELF utilizzato in Linux e altri sistemi.
shared object Può essere identificato come libreria condivisa o formato eseguibile indipendente dalla posizione.
data Si tratta di dati binari che non possono essere identificati sufficientemente come formato noto o testo.
cannot open Il file non può essere aperto a causa del percorso inesistente o per problemi di permessi, ecc.

I risultati non garantiscono l’affidabilità o la sicurezza del file. Il fatto che sia stato riconosciuto come un formato specifico e il giudizio che non contenga codice dannoso sono questioni diverse.

Controllo del tipo MIME e della codifica dei caratteri

Visualizza il tipo MIME e la codifica insieme con -i

MIME significa Multipurpose Internet Mail Extensions; i tipi MIME identificano formati come image/png o text/plain anche nel Web. -i, equivalente a --mime, mostra il tipo insieme alla codifica stimata dei caratteri.

file -i index.html
file --mime README.md

Per un documento HTML contenente testo non ASCII codificato in UTF-8, un risultato possibile è il seguente. Un HTML contenente solo caratteri ASCII può invece riportare charset=us-ascii: il nome index.html da solo non determina il valore.

index.html: text/html; charset=utf-8

Visualizza solo tipo o codifica

--mime-type restituisce soltanto il tipo; --mime-encoding soltanto la codifica rilevata. Per dati binari può comparire binary, che non è una codifica di testo. La rilevazione non distingue necessariamente tutte le codifiche possibili né certifica il significato del contenuto.

file --mime-type image.webp
file --mime-encoding README.md

Usa -b insieme se hai bisogno solo del valore senza il nome del file.

file -b --mime-type image.webp
file -b --mime-encoding README.md

Questi valori aiutano a classificare gli input di un server o di uno script. Un tipo dichiarato dal client e un tipo riconosciuto da file sono però due informazioni diverse: nessuno dei due sostituisce la validazione mediante un parser del formato.

Nomi dei file e separatori nell’output

Omettere il nome con -b

Di norma ogni riga contiene nome: descrizione. -b, o --brief, omette il prefisso con il nome: è la forma da preferire quando vuoi raccogliere soltanto il risultato.

file -b archive.tar.gz
file -b --mime-type photo.jpg

È utile quando si memorizza solo il risultato in una variabile di script.

Gestire spazi e separatori con -N e -F

Nell’output di più file possono essere aggiunti spazi per allineare le descrizioni. -N elimina questo riempimento, mentre -F cambia il separatore tra nome e risultato; non cambia l’ordine dei file.

file -N file1 file-with-long-name.bin
file -F ' => ' file1 file2

Per risultati destinati a un programma, file -00 -- nome1 nome2 separa ogni nome e ogni descrizione con un byte NUL. Una sola -0 aggiunge NUL dopo il nome ma mantiene anche separatore e fine riga. Queste opzioni riguardano l’output: non rendono -f capace di leggere una lista di input delimitata da NUL. Usa un parser che rispetti il formato scelto.

Verifica dei collegamenti simbolici

Esaminare il collegamento stesso

Nel comportamento predefinito normale, i collegamenti simbolici non vengono seguiti e vengono mostrati sia il collegamento stesso sia la sua destinazione. Per specificare questo comportamento, utilizza -h o --no-dereference.

file -h current.log

Poiché il comportamento predefinito può variare a seconda che la variabile d'ambiente POSIXLY_CORRECT sia impostata o meno, è più sicuro specificare le opzioni necessarie negli script.

Verifica delle destinazioni dei collegamenti con -L

-L o --dereference segue i link simbolici per controllare il tipo effettivo del file di destinazione.

file -L current.log
file --dereference latest-image

Se il collegamento è interrotto, il file di destinazione non è accessibile. La descrizione o l’errore risultante dipende dalle opzioni; usa -E se vuoi distinguere anche gli errori del file system tramite uno stato di uscita non zero.

File compressi e contenuto interno

Riconoscere la compressione esterna

Se controlli senza opzioni, generalmente descrive il formato di compressione esterno come gzip, xz, bzip2.

file backup.tar.gz
file archive.xz

Usa -z per decomprimere e ispezionare il formato interno

-z, o --uncompress, tenta di esaminare anche i dati decompressi dei formati supportati. Non estrae un archivio nella directory corrente e non elenca necessariamente tutti i suoi membri: classifica il contenuto che riesce a leggere. -Z chiede di riportare soltanto il formato interno, omettendo la descrizione della compressione.

file -z backup.tar.gz
file --uncompress archive.xz

Il risultato dipende dal supporto di decompressione disponibile e dalle restrizioni del sistema. I file grandi o non affidabili richiedono limiti di risorse appropriati; non disattivare le protezioni del sistema per forzare un riconoscimento. Per ispezionare il contenuto di un archivio usa anche strumenti specifici per quel formato.

Esaminare più file o una lista di percorsi

Selezionare file con i glob della shell

Puoi controllare file con una specifica estensione nella directory corrente contemporaneamente.

file -- ./*.jpg
file -- ./*.sh

Il prefisso ./ evita di passare nomi che iniziano direttamente con un trattino; -- chiude comunque le opzioni. Se non esiste alcuna corrispondenza, Bash normalmente passa il pattern letterale, salvo opzioni come nullglob o failglob. Per molti file preferisci find -exec così da evitare il limite della riga di comando.

Lettura di una lista di nomi di file con -f

-f, o --files-from, legge un percorso per riga. Per una prova nella cartella file-demo, la prima riga seguente crea una piccola lista dei file già preparati. Scegli un altro nome se files-to-check.txt esiste già. Questa forma non può rappresentare senza ambiguità nomi contenenti un carattere di nuova riga.

printf '%s\n' 'README.md' 'utf8.txt' > files-to-check.txt
file -f files-to-check.txt
file -F ' => ' -f files-to-check.txt

-f elabora la lista appena viene incontrata, prima delle opzioni successive. Perciò -F deve precedere -f. Nella seconda prova il separatore diventa => ; i percorsi della lista sono risolti rispetto alla directory in cui esegui il comando, non alla posizione del file di lista.

Input standard e ricerche con find

Controllo del formato dei dati dell'input standard

Specificare un singolo trattino - come nome file legge i dati dall'input standard.

printf '%s\n' 'hello' | file -

In questa prova l’output descrive il testo ASCII ricevuto dal canale di input, con un nome indicativo come /dev/stdin. Un flusso non consente sempre le stesse operazioni di un file regolare, quindi alcuni dettagli del riconoscimento possono differire.

Controllo ricorsivo con find -exec

Per controllare ricorsivamente i file regolari di una directory esistente, combina find e file. Il percorso ./uploads è un esempio: sostituiscilo con la directory effettiva da esaminare.

find ./uploads -type f -exec file -- {} +

{} + passa i percorsi trovati in gruppi compatibili con il limite della riga di comando, preservando spazi e caratteri speciali nei nomi. Qui -- protegge la successiva lista di argomenti. L’output rimane leggibile per una persona e non diventa automaticamente adatto a un parser basato su righe.

Uso dei tipi MIME negli script shell

Salva questo esempio completo in classifica-file.sh e avvialo con bash classifica-file.sh ./image.png, indicando un file esistente. Lo script distingue uso errato o errore di lettura (stato 2), formato non ammesso (stato 1) e tipo immagine ammesso (stato 0). Il controllo con -E è importante: senza questa opzione alcuni errori, come un percorso inesistente, sono descritti nell’output senza rendere non zero lo stato di file.

#!/usr/bin/env bash
if [ "$#" -ne 1 ]; then
  printf '%s\n' 'Uso: bash classifica-file.sh percorso' >&2
  exit 2
fi
path=$1
if ! mime_type=$(file -E -b --mime-type -- "$path"); then
  printf '%s\n' 'Impossibile esaminare il file.' >&2
  exit 2
fi

case "$mime_type" in
  image/jpeg|image/png|image/webp)
    printf '%s\n' 'Tipo immagine ammesso; contenuto da validare.'
    ;;
  *)
    printf '%s\n' "Formato non ammesso: $mime_type" >&2
    exit 1
    ;;
esac

L’esempio verifica soltanto l’appartenenza del tipo riconosciuto a una lista: non apre né convalida l’intera immagine. In un sistema di caricamento reale servono anche un decoder adatto, limiti di dimensione, percorsi di archiviazione separati e le misure previste dalla propria politica di sicurezza. La classificazione non deve essere usata come prova dell’assenza di dati malevoli.

Riepilogo delle principali opzioni

Opzione Descrizione
-b, --brief Omette i prefissi dei nomi dei file nell'output.
-i, --mime Stampa il tipo MIME e la codifica dei caratteri.
--mime-type Stampa solo il tipo MIME.
--mime-encoding Stampa solo le informazioni sulla codifica dei caratteri.
-L, --dereference Segue i collegamenti simbolici per verificare il file di destinazione.
-h, --no-dereference Controlla il collegamento stesso senza seguire i collegamenti simbolici.
-z, --uncompress Esamina, quando possibile, i dati decompressi senza estrarre file nella directory corrente.
-k, --keep-going Continua a cercare altre corrispondenze nelle regole magic dopo la prima.
-f file Legge un elenco di percorsi da verificare dal file specificato.
-F string Cambia il delimitatore tra il nome del file e il risultato.
-N, --no-pad Elimina gli spazi di allineamento dei nomi nell’output; non ordina i file.
-p, --preserve-date Cerca di preservare il tempo di accesso dei file prima di controllarli sui sistemi supportati.
-s, --special-files Legge e controlla file speciali come dispositivi a blocchi o a caratteri. Utilizzare solo quando si comprendono i rischi dell'accesso ai dispositivi.
-E Fa terminare gli errori del file system con un messaggio di errore e uno stato di fallimento invece di essere trattati come risultati normali.
-- Termina l'elaborazione delle opzioni per passare in sicurezza i nomi dei file che iniziano con un trattino.

Come interpretare i limiti del riconoscimento

La classificazione è una stima

file classifica i file basandosi su schemi noti ed euristiche. File danneggiati, formati nuovi o rari, o file che combinano più formati possono produrre risultati ambigui o inattesi.

Un formato riconosciuto non certifica la sicurezza

Anche se identificato come immagine o documento, non significa che non ci siano dati malevoli all'interno. In ambienti sensibili alla sicurezza, fare riferimento insieme all'estensione, al tipo MIME e alla determinazione tramite magic, e utilizzare parser dedicati e verifica basata su policy.

Fai attenzione con file speciali e input di grandi dimensioni

Leggere file di dispositivi con -s o controllare dati compressi con -z può essere più rischioso e costoso rispetto ai controlli normali dei file. Verifica la fonte e la dimensione del target ed esegui con privilegi minimi.

FAQ

Il comando file verifica le estensioni dei file?

La rilevazione principale utilizza informazioni del file system, pattern magici del contenuto, codifica dei caratteri e caratteristiche del testo. Pertanto, anche se non c'è un'estensione o è errata, il formato può essere dedotto basandosi sul contenuto reale.

Come posso ottenere solo il tipo MIME senza il nome del file?

Usa file -b --mime-type filename. -b omette il prefisso del nome del file e --mime-type seleziona solo il tipo MIME.

Come controllo il tipo del file a cui punta un collegamento simbolico?

Usa file -L linkname. Per controllare le informazioni sul collegamento stesso, usa file -h linkname.

Perché il risultato contiene soltanto data?

Potrebbe essere perché non esiste un modello noto che corrisponda al database magic e non può essere identificato come testo. Il file potrebbe essere corrotto, troppo corto o il database magic installato potrebbe non riconoscere quel formato.

Documentazione di riferimento