Comando cp in Linux: copiare file e directory senza confondere i percorsi
cp copia file e, con -R, intere directory in Linux. Prima di eseguirlo, controlla se la destinazione esiste già: può cambiare il percorso finale e, senza protezioni, sovrascrivere file esistenti.
Gli esempi si riferiscono a GNU Coreutils. Controlla cp --help e man cp sul sistema di destinazione: opzioni come -a, -T e --update=none non sono disponibili in tutte le implementazioni o versioni.
Cos'è il comando cp?
cp legge la sorgente e scrive una copia nella destinazione. Un nuovo file normale ha una propria identità nel filesystem, rappresentata in Linux dall’inode, e modificarne il contenuto non modifica la sorgente. Un file di destinazione già esistente può invece essere riscritto mantenendo il suo inode. Con il copy-on-write, i due file possono inizialmente condividere blocchi fisici: una copia logica distinta non equivale a un backup su un altro supporto.
Sintassi di base
cp [OPTION]... [-T] SOURCE DESTINATION
cp [OPTION]... SOURCE... DIRECTORY
cp [OPTION]... -t DIRECTORY SOURCE...
Racchiudi tra virgolette i percorsi con spazi. In GNU Coreutils, -- termina le opzioni prima di nomi che iniziano con un trattino. La sintassi precedente è uno schema con segnaposto: non copiarne letteralmente le parentesi.
Uso base di cp
Copiare un file con un nuovo nome
Prepara una cartella nuova con mkdir cp-demo && cd cp-demo; se esiste già, scegli un altro nome. Crea un file di prova con printf "rapporto\n" > report.txt. Il comando seguente crea report-backup.txt se il nome non esiste; se esiste già come file, può sovrascriverlo.
cp report.txt report-backup.txt
Copiare più file in una directory
Crea i bersagli di prova con mkdir public, printf "pagina\n" > index.html e printf "stile\n" > style.css. Con più sorgenti, l’ultimo argomento deve essere una directory esistente: i risultati saranno public/index.html e public/style.css.
cp index.html style.css public/
Copiare una gerarchia di directory
Prepara due directory nuove con mkdir src app e inserisci un file in ciascuna, ad esempio con printf "codice\n" > src/main.txt e printf "configurazione\n" > app/settings.conf. Con le destinazioni ancora assenti, i comandi seguenti creano src-copy/main.txt e app-backup/settings.conf. -R abilita la ricorsione; -a aggiunge la conservazione di collegamenti e attributi nei limiti supportati.
cp -R src src-copy
cp -a app/ app-backup/
Verificare che il contenuto copiato coincida
cp normalmente non stampa nulla in caso di successo. Questo esempio usa una sottocartella nuova e interrompe la prova se la preparazione o la copia fallisce, evitando di riutilizzare file precedenti. Le parentesi eseguono la prova in una subshell senza cambiare la directory della shell principale.
(
mkdir copy-check || exit 1
cd copy-check || exit 1
printf 'demo\n' > original.txt
cp original.txt copy.txt || exit 1
cmp -s original.txt copy.txt
echo $?
)
L’output atteso è 0, il codice restituito da cmp -s: i due file hanno lo stesso contenuto in byte. 1 indica una differenza e un valore maggiore un errore. Questo codice non è quello di cp e non verifica permessi, proprietario o attributi estesi; per i metadati consulta anche la guida al comando stat.
Opzioni principali
| Opzione | Scopo |
|---|---|
-R, -r |
Copia le directory ricorsivamente. |
-a |
Modalità archivio: ricorsione e conservazione di collegamenti e attributi per quanto possibile; non garantisce una copia di sicurezza completa. |
-p |
Conserva permessi, proprietario/gruppo e tempi di accesso e modifica, nei limiti di privilegi e filesystem. |
-i |
Chiede conferma prima di sovrascrivere una destinazione esistente. |
-n |
Non sovrascrive i file esistenti. Nella documentazione GNU 9.10 e 9.12 è deprecata per le differenze nel codice di uscita tra piattaforme. |
-u |
Copia quando la destinazione manca o ha un tempo di modifica precedente alla sorgente. Non confronta il contenuto. |
-T |
Usa esattamente il percorso di destinazione, senza aggiungervi automaticamente il nome della sorgente. Con -R la destinazione può comunque essere una directory. |
-t DIR |
Specifica la directory di destinazione prima dell'elenco delle sorgenti. |
--reflink[=WHEN] |
Controlla il copy-on-write (CoW): i blocchi possono essere condivisi fino a una modifica. always richiede supporto, auto ripiega sulla copia ordinaria, never lo disattiva. |
Le opzioni lunghe rendono spesso più espliciti gli script GNU. Per la portabilità confronta cp in POSIX.1-2024: non assume tutte le estensioni GNU. Per i link simbolici in copie ricorsive, specifica deliberatamente -H, -L o -P secondo l’effetto desiderato.
Esempi pratici
Controllare la sovrascrittura
Prepara backup con mkdir backup e file di prova chiamati config.ini e almeno un file .conf. -i chiede conferma soltanto se il file di destinazione esiste: prova prima con una copia in backup, poi ripeti rispondendo negativamente e verifica che il contenuto resti invariato. Il secondo comando usa -n, ancora comune ma deprecato nei manuali GNU 9.10 e 9.12. Nelle versioni che le supportano, --update=none salta i file esistenti senza errore e --update=none-fail li salta con diagnostica ed esito di errore. Controlla cp --help: il semplice successo del comando non dimostra che ogni file sia stato copiato. Il pattern *.conf è espanso dalla shell; in Bash normalmente esclude i nomi nascosti e, se non trova corrispondenze, può restare letterale.
cp -iv config.ini backup/
cp -nv *.conf backup/
Conservare gli attributi nella copia
-a equivale sostanzialmente a -dR --preserve=all, con meno diagnostica: copia i link simbolici come link e mantiene i legami fra hard link della sorgente. Le liste di controllo degli accessi (ACL), gli attributi estesi (xattr), le etichette SELinux e proprietario/gruppo dipendono da privilegi e filesystem. Alcuni mancati ripristini di contesti SELinux o xattr non causano necessariamente un codice di uscita di errore: verifica gli attributi importanti. Il primo comando riguarda percorsi di sistema da adattare alla propria applicazione e a un supporto di backup preparato; non eseguirlo nel laboratorio. Per il secondo, crea una directory di prova source con un file e lascia inizialmente assente destination.
sudo cp -a /etc/myapp/ /backup/myapp/
cp -a --preserve=all source/ destination/
Verificare le copie importanti
Per usare i comandi seguenti nel laboratorio, prepara source.img e copialo in copied.img; crea anche source-dir con un file e copialo con cp -R source-dir copied-dir, lasciando inizialmente assente copied-dir. I due hash SHA-256 devono coincidere, indipendentemente dai nomi stampati. diff -qr non stampa differenze e restituisce zero se le gerarchie confrontate coincidono; non verifica tutti i metadati. Se i dati cambiano durante la lettura, una verifica successiva non garantisce un’istantanea coerente: per database e servizi attivi usa procedure di backup adatte all’applicazione.
sha256sum source.img copied.img
diff -qr source-dir copied-dir
Scegliere come trattare i link simbolici
Un link simbolico contiene un percorso verso un altro elemento. Senza ricorsione, GNU cp link copia normalmente segue il link sorgente e copia il file a cui punta. -P copia il link stesso, -L segue tutti i link sorgente e -H segue soltanto quelli passati sulla riga di comando. -a implica -P; l’ultima opzione pertinente prevale. Nella destinazione, un link verso un file normale esistente può invece essere seguito: verifica anche dove punta il bersaglio prima di scrivere. La conservazione dei link è distinta dalla scelta di usare una copia CoW.
cp e comandi correlati
| Comando o metodo | Ruolo principale | Quando usarlo |
|---|---|---|
cp |
Copia di file e directory locali | Copie semplici |
mv |
Sposta o rinomina percorsi | Quando il file non deve restare nel percorso originale |
rsync |
Sincronizzazione incrementale e remota | Copie ripetute di grandi quantità di dati o trasferimenti in rete |
install |
Copia impostando attributi | Installazione e distribuzione di programmi |
Avvertenze importanti
La destinazione cambia il percorso finale
Con GNU cp -a app/ app-backup/, se app-backup non esiste viene creata come copia di app; se esiste già come directory, la copia finisce sotto app-backup/app. cp -aT app app-backup tratta app-backup come destinazione esatta; cp -at app-backup app mette invece app al suo interno. Nessuna di queste forme rimuove file extra già presenti nella destinazione: cp non è una sincronizzazione con cancellazione.
La modalità archivio non è un sistema di backup completo
File aperti, database attivi, privilegi e funzioni del filesystem non supportate possono impedire una copia coerente e completa. Conserva una copia separata, verifica diagnostica e attributi necessari e prova il ripristino. Per annullare il laboratorio, esamina prima la cartella cp-demo e rimuovi soltanto i file e le directory creati per la prova.
I glob della shell possono omettere voci nascoste
Un pattern come source/* normalmente esclude i nomi che iniziano con un punto. Con GNU cp -a source/. dest/, con dest preparata, copi invece il contenuto della directory, inclusi gli elementi nascosti. La barra finale della sorgente non ha il significato speciale di esclusione del nome di directory usato da rsync; controlla i percorsi ottenuti con un piccolo esempio.
FAQ
Devo usare -R o -a per una directory?
Usa -R per la ricorsione di base e -a per conservare anche collegamenti e attributi supportati. Su sistemi non GNU, il comportamento di -r sui link e sui file speciali può differire: verifica il manuale e preferisci opzioni esplicite.
Come posso evitare di sovrascrivere i file esistenti?
-n evita la sovrascrittura, ma i manuali GNU 9.10 e 9.12 la deprecano. Se supportate dalla versione installata, usa --update=none per ignorare i file esistenti senza errore oppure --update=none-fail per segnalare il mancato aggiornamento. Verifica comunque il contenuto ottenuto.
Perché una directory copiata appare a una profondità diversa da quella attesa?
Se la destinazione esiste come directory, la sorgente viene copiata al suo interno. Se è assente, con una sola sorgente diventa il nome della copia. -T usa la destinazione esatta; -t indica una directory contenitore esistente.
Come posso verificare una copia?
Confronta gli hash dei file e usa diff -qr per le directory. Verifica anche gli attributi che contano per l’applicazione e prova il ripristino del backup; un confronto dei soli dati non certifica tutti i metadati.




