Comando cmp in Linux: confrontare file byte per byte e interpretare il risultato
Il comando cmp confronta due file byte per byte: se sono uguali non stampa nulla, mentre normalmente segnala la prima differenza e la sua posizione. È utile per controllare copie di file, anche binari, e individuare il primo byte diverso senza produrre un confronto riga per riga.
Gli esempi si riferiscono a GNU cmp, incluso in GNU Diffutils, eseguito da una shell come Bash. Controlla cmp --version, cmp --help e man cmp sul sistema: POSIX standardizza -l e -s, mentre opzioni come -n e -i e la sintassi degli offset dipendono dall’implementazione. Cmp legge gli input; solo i comandi di preparazione degli esempi creano file.
Cos'è il comando cmp?
GNU cmp restituisce 0 se non trova differenze nel confronto richiesto, 1 se gli input differiscono e 2 se incontra un problema, per esempio un input mancante. In POSIX gli errori hanno stato maggiore di 1. Per leggere le modifiche tra righe di testo, diff e il suo formato unificato sono più informativi. I file non devono essere ordinati per usare cmp.
Sintassi di base
cmp [OPTION]... FILE1 [FILE2 [SKIP1 [SKIP2]]]
OPTION, FILE1 e gli altri nomi sono segnaposto. Usa percorsi esistenti e virgolette per nomi con spazi, per esempio cmp -- "copia vecchia.bin" "copia nuova.bin". In GNU cmp FILE2 omesso, oppure un argomento -, indica lo standard input; evita di usare lo stesso flusso come entrambi gli input. SKIP1 e SKIP2 sono quantità di byte da saltare, non numeri di riga.
Uso di base di cmp
Confrontare due file
Con due file regolari esistenti, cmp confronta il contenuto e si ferma al primo byte diverso. Se uno è soltanto un prefisso identico dell’altro, segnala la fine del file più corto, indicata da EOF, e restituisce comunque 1. Non confronta directory, nomi, proprietari o permessi.
cmp image-a.bin image-b.bin
Verificare l’uguaglianza senza output normale
-s evita i messaggi sulle differenze: il risultato si legge dallo stato di uscita. Non interpretare quindi il silenzio come uguaglianza. Anche un input mancante può non produrre un messaggio con -s in GNU cmp; occorre distinguere 0, 1 e 2, come nello script completo più avanti.
cmp -s copy.iso original.iso
Confrontare soltanto la parte iniziale
L’opzione GNU -n 4096 confronta al massimo i primi 4096 byte. Uno stato 0 non certifica il resto del file e non dimostra che siano stati letti 4096 byte: due file identici ma più corti possono terminare normalmente. Se solo uno termina prima e l’altro ha ancora byte entro il limite, il confronto segnala la differenza.
cmp -n 4096 file-a file-b
Leggere la posizione del primo byte diverso
La prova completa seguente crea due file da un byte in una cartella nuova. Se cmp-demo esiste già, si ferma: scegli un nome diverso, senza sovrascrivere i dati della prova precedente. Le parentesi mantengono locale il cambio di directory. LC_ALL=C rende prevedibile la lingua del messaggio per questo comando.
(
mkdir cmp-demo || exit 1
cd cmp-demo || exit 1
printf 'A' > first.bin || exit 1
printf 'B' > second.bin || exit 1
stato=0
LC_ALL=C cmp first.bin second.bin || stato=$?
printf 'Stato: %s\n' "$stato"
case "$stato" in 0|1) ;; *) exit "$stato" ;; esac
)
Un possibile messaggio del confronto, prima della riga finale Stato: 1:
first.bin second.bin differ: char 1, line 1
Byte e righe sono numerati da 1. Nel messaggio di alcune implementazioni, char è un termine storico per la posizione in byte: non significa un carattere Unicode. Il numero di riga conta i caratteri di nuova riga incontrati e non trasforma un file binario in testo. Per distinguere la differenza da un errore, conserva subito lo stato di uscita.
Opzioni principali
| Opzione | Scopo |
|---|---|
-s, --silent |
Non stampa il normale risultato del confronto; lo stato distingue uguaglianza, differenza ed errore. I messaggi di errore possono dipendere dall’implementazione. |
-l, --verbose |
Elenca le posizioni dei byte diversi in decimale e i due valori in ottale, prima quello di FILE1 e poi quello di FILE2. |
-b, --print-bytes |
Mostra anche i valori dei byte diversi e una loro rappresentazione; non decodifica il formato binario. |
-i SKIP |
Salta SKIP byte all’inizio di entrambi gli input; il conteggio parte da zero byte saltati. |
-i SKIP1:SKIP2 |
Salta SKIP1 byte nel primo input e SKIP2 nel secondo, nella sintassi GNU. |
-n LIMIT |
Confronta al massimo LIMIT byte, dopo gli eventuali salti; non controlla automaticamente la lunghezza minima attesa. |
Esempi pratici
Distinguere uguaglianza, differenza ed errore nello script
Questo esempio autonomo crea due configurazioni diverse in una nuova cartella cmp-script-demo. Acquisisce lo stato invece di analizzare messaggi tradotti e non classifica un errore di lettura come una differenza. Il risultato atteso è File diversi con stato 1 del sottoprocesso. Per usarlo sui tuoi file esistenti, sostituisci i percorsi nel confronto e ometti la preparazione dimostrativa; non sovrascrivere configurazioni reali per creare la prova.
(
mkdir cmp-script-demo || exit 1
cd cmp-script-demo || exit 1
printf 'port=9090\n' > generated.conf || exit 1
printf 'port=8080\n' > current.conf || exit 1
stato=0
cmp -s generated.conf current.conf || stato=$?
case "$stato" in
0) printf '%s\n' 'Nessuna differenza' ;;
1) printf '%s\n' 'File diversi' ;;
*) printf 'Errore di confronto: %s\n' "$stato" >&2 ;;
esac
exit "$stato"
)
Confrontare una regione di intestazione fissa
Se conosci il formato, puoi limitare la verifica ai primi 512 byte di due immagini già esistenti. Uno stato 0 riguarda solo quella porzione: contenuto successivo, validità del formato e presenza di un’intestazione completa di 512 byte richiedono verifiche separate. Questo comando non apre né modifica un disco fisico.
cmp -n 512 disk-a.img disk-b.img
Saltare le intestazioni del contenitore
-i 4096 esclude i primi 4096 byte di entrambi i file e confronta ciò che resta. Usa questo valore solo se la dimensione dell’intestazione è davvero nota. Per intestazioni diverse, GNU accetta per esempio cmp -i 16:32 file-a file-b; per controllare al massimo 100 byte dopo quei salti, aggiungi -n 100. Se entrambi gli input sono già terminati dopo il salto, lo stato può essere 0 senza aver confrontato alcun byte del contenuto utile.
Con GNU cmp la numerazione dei byte riportata dopo un salto riparte dalla porzione confrontata. Se salti 4096 byte e il messaggio indica il byte 1, l’offset da zero nel file originale è 4096. Con salti diversi, per ciascun input somma il relativo SKIP alla posizione riportata meno uno. Non confondere quindi la posizione stampata con un offset assoluto da passare a un altro strumento.
cmp -i 4096 payload-a.bin payload-b.bin
cmp e comandi correlati
| Comando | Ruolo principale | Quando usarlo |
|---|---|---|
cmp |
Confronto diretto dei byte e prima differenza | Verificare copie e localizzare il primo byte diverso |
diff |
Modifiche del testo riga per riga | Leggere cambiamenti in sorgenti e configurazioni |
sha256sum |
Calcolo separato dell’impronta di ciascun file | Confrontare valori conservati o forniti da una fonte attendibile |
comm |
Confronto di righe già ordinate con lo stesso criterio | Separare righe comuni e presenti in un solo input, considerando gli eventuali duplicati |
Avvertenze importanti
Limitare l’output dettagliato quando serve
cmp -l file1 file2 può stampare una riga per ogni byte diverso prima della fine del file più corto. Una riga come 1 101 102 indica la posizione decimale 1 e i valori ottali 101 e 102, corrispondenti ad A e B in ASCII. Se un file termina prima dell’altro, cmp segnala EOF: -l non inventa valori per la parte assente. Per un semplice controllo di uguaglianza usa -s; per un’ispezione circoscritta combina le opzioni GNU con un limite -n.
Separare le differenze dagli errori
Un costrutto if cmp -s ...; then ...; else ...; fi con una sola alternativa confonde lo stato 1 con gli errori. Acquisisci invece il risultato immediatamente, come nell’esempio completo. La forma stato=0; cmp -s ... || stato=$? permette di gestirlo anche quando la shell usa set -e. Non aggiungere -s e -l insieme: chiedono modalità di output incompatibili.
Non confondere l’uguaglianza con l’autenticità
Cmp controlla i byte confrontati, non origine, firma digitale o validità del formato. Anche la corrispondenza di un hash ricevuto da una fonte non affidabile non autentica il file. Per una verifica ripetibile confronta file stabili, che altri processi non stanno modificando: cmp non crea una fotografia atomica dei due input.
FAQ
L’assenza di output significa che i file sono uguali?
Solo uno stato 0 indica nessuna differenza nel confronto richiesto. Con -s anche file diversi o un errore possono non produrre messaggi; con -n o -i lo stato 0 può riguardare soltanto una porzione, anche vuota.
Come posso vedere tutte le differenze in byte?
Usa cmp -l con i due file. Le posizioni sono decimali, i valori dei byte ottali; se un file finisce prima, viene segnalato EOF. L’output può essere molto lungo.
Cmp può confrontare file di testo?
Sì, cmp confronta anche file di testo senza interpretarli. Per leggere righe aggiunte o rimosse usa diff; codifica e terminatori di riga possono rendere diversi file che sembrano uguali a schermo.
Qual è la differenza tra cmp e un checksum?
Cmp confronta direttamente i due input; un checksum o hash produce un valore per ciascun file, comodo da conservare o confrontare tra sistemi. Cmp localizza la prima differenza e non richiede di calcolare prima un’impronta completa.




