Comando find di Linux: opzioni -name, -type, -size, -mtime e -delete
Il comando find di Linux scende a partire da una cartella iniziale e trova file e cartelle che soddisfano condizioni come nome, tipo, dimensione, orario di modifica e permessi. Creando dieci file in una cartella di prova di un server AlmaLinux 9 ed eseguendolo cambiando una condizione alla volta, abbiamo finito per passare i file trovati con -exec ad altri comandi e, per eliminare, per controllare prima l'elenco con le stesse condizioni, prima di -delete.
I percorsi della cartella di prova e gli orari dei file nei riquadri dei risultati sono stati cambiati con valori di esempio. Nell'output del server Debian 12 solo il percorso della cartella home è un valore di esempio, il resto è invariato.
1️⃣ Come usare il comando find di Linux
La forma di base è [find percorso-iniziale condizioni]. Senza percorso iniziale cerca nella cartella corrente (.), e senza condizioni stampa tutti i file e le cartelle sotto il percorso iniziale.
La prova è stata fatta in /root/work, con tre cartelle e dieci file come qui sotto.
find /root/work/root/work
/root/work/docs
/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/backup
/root/work/report.txt
/root/work/README.md
/root/work/run.sh
/root/work/my notes.txt
/root/work/empty.txtfind non ordina i risultati per nome; in questa esecuzione, arrivato alla cartella docs, ha stampato prima tutti i file al suo interno e poi è passato a logs.
Se scrivi più condizioni di seguito, restano solo i file che le soddisfano tutte.
-name confronta con il pattern solo il nome del file, non il percorso. Racchiudi il pattern tra virgolette semplici, così la shell non espande prima * e lo passa così com'è a find.
find /root/work -name '*.txt'/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/report.txt
/root/work/my notes.txt
/root/work/empty.txt-name distingue maiuscole e minuscole. Cercando i nomi che iniziano con readme è comparso solo docs/readme.txt, e con -iname anche README.md.
find /root/work -name 'readme*'/root/work/docs/readme.txtfind /root/work -iname 'readme*'/root/work/docs/readme.txt
/root/work/README.mdfind fa parte del pacchetto findutils. La versione nella prima riga di [find --version] era findutils 4.8 sul server AlmaLinux 9.8 e 4.9 sul server Debian 12.
2️⃣ find -type d e -maxdepth
-type f tiene solo i file normali e -type d solo le cartelle.
find /root/work -type d/root/work
/root/work/docs
/root/work/logs
/root/work/backupAnche il percorso iniziale /root/work è una cartella, quindi è comparso nella prima riga. Con -type f sullo stesso percorso sono comparsi tutti e dieci i file.
-maxdepth stabilisce di quanti livelli scendere dal percorso iniziale. Con -maxdepth 1 i file in docs e logs sono usciti e sono rimasti solo i cinque file subito sotto /root/work.
find /root/work -maxdepth 1 -type f/root/work/report.txt
/root/work/README.md
/root/work/run.sh
/root/work/my notes.txt
/root/work/empty.txtAl contrario, -mindepth 2 ha saltato ciò che sta subito sotto il percorso iniziale e ha stampato solo i cinque file nelle sottocartelle.
find /root/work -mindepth 2 -type f/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmpLa pagina man consiglia di scrivere le opzioni globali come -maxdepth subito dopo il percorso iniziale. Anche -maxdepth 1 dopo -type f ha dato gli stessi cinque file, ma nel terminale compare una riga di avviso che invita a mettere prima le opzioni globali (secondo la pagina man).
Per sapere solo quante cartelle o quanti file ci sono, passa l'output a wc -l. Il conteggio dell'output di -type d ha dato 4, percorso iniziale compreso.
find /root/work -type d | wc -l4Anche con -maxdepth 1 il risultato è stato 4, perché tutte e tre le sottocartelle stanno subito sotto il percorso iniziale.
find /root/work -maxdepth 1 -type d | wc -l4Contando con -mindepth 2 solo i file nelle sottocartelle il risultato è stato 5.
find /root/work -mindepth 2 -type f | wc -l53️⃣ Condizioni di dimensione e tempo del comando find
Il + prima di un numero significa maggiore di quel valore, il - minore, e senza segno esattamente quel valore. Le unità di -size sono nella tabella qui sotto (secondo la pagina man).
| Unità | Dimensione | Sì |
|---|---|---|
| c | 1 byte | -size +500c |
| k | 1,024 byte | -size +1k |
| M | 1,048,576 byte | -size +1M |
| G | 1,073,741,824 byte | -size +1G |
| (nessuna) | Blocchi da 512 byte | -size +2 |
find /root/work -type f -size +1k/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txtI file più grandi di 1k erano guide.txt da 5,000 byte, app.log da 2MB e report.txt da 1,200 byte.
find /root/work -size +1M/root/work/logs/app.logScrivendo -size due volte per stabilire un intervallo sono rimasti solo i due file più grandi di 1k e più piccoli di 100k.
find /root/work -type f -size +1k -size -100k/root/work/docs/guide.txt
/root/work/report.txt-size divide la dimensione per l'unità e arrotonda per eccesso prima di confrontare. Per questo anche README.md da 300 byte conta come 1k, e con -size -1k è comparso solo empty.txt, di dimensione 0.
find /root/work -type f -size -1k/root/work/empty.txtPer provare le condizioni di tempo abbiamo impostato l'orario di modifica di README.md, my notes.txt e docs/readme.txt a 3 giorni fa e quello dei due file .tmp a 10 giorni fa. Ogni file conserva tre orari, accesso, modifica e cambiamento, che puoi vedere con il comando stat.
-mtime conta il tempo dall'ultima modifica in unità di 24 ore. Con -mtime -1 sono comparsi i cinque file creati nelle ultime 24 ore.
find /root/work -type f -mtime -1/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txtCon -mtime +7 sono comparsi solo i due file .tmp impostati a 10 giorni fa. Questa forma serve a controllare l'elenco prima di eliminare vecchi log o file temporanei.
find /root/work -type f -mtime +7/root/work/docs/old.tmp
/root/work/logs/cache.tmp-mmin fa lo stesso calcolo in minuti. Il risultato di -mmin -60 sono stati gli stessi cinque file di -mtime -1.
find /root/work -type f -mmin -60/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txt-newer trova i file modificati dopo un file di riferimento. Con README.md, impostato a 3 giorni fa, come riferimento sono comparsi i cinque file creati dopo.
find /root/work -type f -newer /root/work/README.md/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txt-empty trova insieme i file di dimensione 0 e le cartelle vuote, e sono comparsi la cartella vuota backup ed empty.txt.
find /root/work -empty/root/work/backup
/root/work/empty.txt4️⃣ Condizioni -perm e -user di find
Con un solo numero dopo -perm cerca i file con permessi esattamente di quel valore. Con -perm 644 sono usciti run.sh a 755 e my notes.txt a 600, e sono comparsi otto file.
find /root/work -type f -perm 644/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/report.txt
/root/work/README.md
/root/work/empty.txtCon - prima del modo cerca i file che hanno tutti i permessi indicati. Solo run.sh aveva il permesso di esecuzione del proprietario (u+x).
find /root/work -type f -perm -u+x/root/work/run.shCon / prima del modo basta avere uno dei permessi indicati. 6000 è la somma di SUID (4000) e SGID (2000), e questa forma serve a controllare sul server i file che, una volta eseguiti, operano con i permessi del proprietario o del gruppo.
La cartella di prova non ne aveva, quindi abbiamo dato SUID a run.sh ed eseguendo è comparso run.sh.
chmod u+s /root/work/run.shfind /root/work -type f -perm /6000/root/work/run.shNei materiali vecchi in quel punto c'è -perm +6000. Eseguito così com'è, è terminato con l'errore [invalid mode].
find /root/work -type f -perm +6000find: invalid mode '+6000'La forma + è stata rimossa in findutils 4.5.12 (secondo la pagina man), quindi scrivi /. Il SUID dato per la prova è stato tolto con chmod u-s.
-user filtra per nome del proprietario. Tutti i file di prova sono di root, quindi -user root da solo non filtra nulla; aggiungendo -name per scegliere i file .log è rimasto solo app.log.
find /root/work -type f -user root -name '*.log'/root/work/logs/app.log-nouser trova i file il cui UID proprietario non ha un account. Si usa per controllare i file rimasti sul server dopo l'eliminazione di un account; cambiando il proprietario di guide.txt con l'UID inesistente 1500 è comparso guide.txt.
chown 1500:1500 /root/work/docs/guide.txtfind /root/work -nouser/root/work/docs/guide.txt-nogroup fa lo stesso controllo sul gruppo, ed è comparso guide.txt, con il gruppo anch'esso cambiato in 1500. Dopo la prova abbiamo ripristinato con chown root:root.
Con -o tra le condizioni ne basta una. Se lo usi con un'altra condizione come -type f, raggruppa tra parentesi le condizioni unite da -o. Metti una barra rovesciata davanti alle parentesi perché la shell non le interpreti prima, e lascia spazi tra parentesi e condizioni.
find /root/work -type f \( -name '*.log' -o -name '*.tmp' \)/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp! inverte la condizione subito dopo. Cercando i file che non sono .txt ne sono comparsi cinque.
find /root/work -type f ! -name '*.txt'/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/README.md
/root/work/run.sh5️⃣ Usare find -exec
-exec esegue il comando scritto dopo per ogni file trovato, con il percorso trovato al posto di {}. Il ; alla fine del comando si scrive \; perché la shell non lo legga prima come separatore di comandi.
find /root/work -name '*.log' -exec ls -l {} \;-rw-r--r-- 1 root root 2097152 Oct 5 14:10 /root/work/logs/app.logSe termini con + invece di \;, i percorsi trovati vengono raccolti e il comando viene eseguito una sola volta. Confrontando con echo, \; ha stampato i cinque percorsi su cinque righe e + su una.
find /root/work -name '*.txt' -exec echo {} \;/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/report.txt
/root/work/my notes.txt
/root/work/empty.txtfind /root/work -name '*.txt' -exec echo {} +/root/work/docs/readme.txt /root/work/docs/guide.txt /root/work/report.txt /root/work/my notes.txt /root/work/empty.txtI comandi che accettano più percorsi, come ls, si raggruppano con + per ridurre le esecuzioni. Abbiamo controllato la dimensione dei tre file più grandi di 1k con un solo ls -lh.
find /root/work -type f -size +1k -exec ls -lh {} +-rw-r--r-- 1 root root 4.9K Oct 5 14:10 /root/work/docs/guide.txt
-rw-r--r-- 1 root root 2.0M Oct 5 14:10 /root/work/logs/app.log
-rw-r--r-- 1 root root 1.2K Oct 5 14:10 /root/work/report.txt-exec serve anche a impostare in massa i permessi di una cartella web, 644 per i file e 755 per le cartelle. Prima di eseguirlo abbiamo cercato i file con valori diversi, e sono comparsi run.sh e my notes.txt.
find /root/work -type f ! -perm 644/root/work/run.sh
/root/work/my notes.txtFile e cartelle hanno permessi diversi, quindi esegui separatamente -type f e -type d. Anche chmod accetta più percorsi, perciò abbiamo terminato con +.
find /root/work -type f -exec chmod 644 {} +find /root/work -type d -exec chmod 755 {} +Cercando di nuovo con la stessa condizione non è comparso nulla, e anche la cartella backup, impostata prima a 700, è passata a 755.
Però anche run.sh è passato a 644 ed eseguendolo è comparso [Permission denied]. Nelle cartelle con eseguibili mescolati, ridai a questi file il permesso di esecuzione con chmod +x.
Per cambiare solo i file nelle sottocartelle aggiungi -mindepth 2. Con 660 sono cambiati solo i cinque file di docs e logs, e dopo il controllo siamo tornati a 644.
find /root/work -mindepth 2 -type f -exec chmod 660 {} +find /root/work -type f -perm 660/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmpUnendo find e grep cerchi per contenuto del file e non per nome. Per simulare un controllo di web shell abbiamo creato quattro file PHP nella cartella separata /root/site e messo la stringa [base64_decode] in html-cache.php e photo.php della cartella upload.
find /root/site -type f/root/site/lib/func.php
/root/site/upload/html-cache.php
/root/site/upload/photo.php
/root/site/index.phpSe conosci il nome della web shell, cercala con -name. Aggiungendo -maxdepth 2 per scendere solo fino alla cartella upload è comparso solo html-cache.php.
find /root/site -maxdepth 2 -type f -name 'html*.php'/root/site/upload/html-cache.phpphoto.php, con un nome comune, qui non è comparso. grep -l eseguito con -exec stampa solo i percorsi dei file con la stringa, e sono comparsi entrambi i file.
find /root/site -name '*.php' -exec grep -l 'base64_decode' {} +/root/site/upload/html-cache.php
/root/site/upload/photo.php[base64_decode] è una funzione presente anche nei file del core di WordPress, quindi apri i file trovati e controlla il contenuto prima di eliminarli.
-print0 mette un carattere nullo invece di un ritorno a capo tra i percorsi. Il carattere nullo non si vede a schermo, quindi i percorsi sono usciti attaccati su una riga.
find /root/work -name '*.txt' -print0/root/work/docs/readme.txt/root/work/docs/guide.txt/root/work/report.txt/root/work/my notes.txt/root/work/empty.txtPer passare a un altro comando nomi con spazi come my notes.txt senza spezzarli, l'output di -print0 si usa in coppia con xargs -0 (secondo la pagina man).
6️⃣ Eliminare file con find e opzioni
Prima di eliminare, esegui le stesse condizioni senza eliminare e controlla a occhio l'elenco dei file da eliminare.
find /root/work -name '*.tmp'/root/work/docs/old.tmp
/root/work/logs/cache.tmp-exec rm {} \; esegue rm per ogni file trovato. Eseguito solo nella cartella logs ha eliminato cache.tmp ed è rimasto solo app.log.
find /root/work/logs -name '*.tmp' -exec rm {} \;ls /root/work/logsapp.log-delete fa eliminare direttamente a find senza eseguire rm. All'esecuzione non ha stampato nulla, e cercando di nuovo con la stessa condizione non c'erano più file .tmp.
find /root/work -name '*.tmp' -deletefind /root/work -name '*.tmp'-delete va sempre dopo le condizioni. find valuta la riga di comando dall'inizio come un'unica espressione, quindi con -delete in testa tenta di eliminare tutto sotto il percorso iniziale prima di guardare le condizioni (secondo la pagina man).
🔲 Opzioni del comando find
📌 Opzioni principali: risultati di questo articolo
| Opzione | Compito | Risultato in questo articolo | |
|---|---|---|---|
| -name | Trova i nomi che corrispondono a un pattern (distingue maiuscole) | '*.txt' dà cinque file; 'readme*' solo docs/readme.txt | |
| -iname | Confronta i nomi senza distinguere maiuscole | 'readme*' dà docs/readme.txt e README.md | |
| -type f, -type d | Tiene solo file normali (f) o cartelle (d) | -type d dà quattro cartelle con il percorso iniziale; -type f dieci file | |
| -maxdepth | Scende solo di N livelli sotto il percorso iniziale | -maxdepth 1 lascia solo i cinque file subito sotto /root/work | |
| -mindepth | Salta i livelli sopra N dal percorso iniziale | -mindepth 2 dà solo i cinque file nelle sottocartelle | |
| -size | Cerca per dimensione (+ più grande, - più piccolo, unità c, k, M, G) | -size +1k dà tre file; -size -1k solo empty.txt | |
| -mtime | Confronta il tempo dalla modifica del contenuto in unità di 24 ore | -mtime -1 dà cinque file; -mtime +7 due file .tmp | |
| -mmin | Confronta il tempo dalla modifica in minuti | -mmin -60 dà gli stessi cinque file di -mtime -1 | |
| -ctime | Confronta in unità di 24 ore fino al cambio dei dati del file, come permessi e nome | -ctime -1 dà tutti e dieci i file di prova | |
| -newer | Trova ciò che è stato modificato dopo un file di riferimento | Cinque file con README.md, impostato a 3 giorni fa, come riferimento | |
| -empty | Trova file di dimensione 0 e cartelle vuote | Dà la cartella vuota backup ed empty.txt | |
| -perm | Cerca per permessi (solo numero: esattamente quel valore; - davanti: tutti quelli indicati; / davanti: almeno uno) | -perm 644 dà otto file, -perm -u+x dà run.sh e -perm /6000 dà run.sh dopo il SUID | |
| -user | Filtra per nome del proprietario | Con -name '*.log' dà app.log; un account inesistente termina con errore | |
| -nouser | Trova ciò che ha un UID proprietario senza account | Dà guide.txt, con l'UID cambiato in 1500 | |
| -nogroup | Trova ciò che ha un GID di gruppo senza gruppo | Dà guide.txt, con il GID cambiato in 1500 | |
| -o | Tiene ciò che soddisfa una delle due (tra parentesi con altre condizioni) | Raggruppando .log e .tmp compaiono tre file | |
| ! | Inverte la condizione subito dopo | Dà cinque file che non sono .txt | |
| -exec | Esegue il comando scritto dopo per ogni file trovato (percorso al posto di {}) | Terminando con +, un solo echo stampa cinque percorsi su una riga | |
| -print0 | Mette un carattere nullo invece di un ritorno a capo tra i percorsi | Il carattere nullo non si vede, i percorsi sono attaccati su una riga | |
| -delete | find elimina direttamente i file trovati (va dopo le condizioni) | Nessun output; cercando di nuovo non c'erano file .tmp |
📎 Altre opzioni: secondo il manuale ufficiale
| Opzione | Compito | |
|---|---|---|
| -L | Segue i link simbolici e usa i dati del file di destinazione | |
| -path | Confronta l'intero percorso, non il nome, con un pattern della shell | |
| -regex | Confronta l'intero percorso con un'espressione regolare | |
| -iregex | Confronta come -regex, senza distinguere maiuscole | |
| -atime | Confronta il tempo dall'ultimo accesso in unità di 24 ore | |
| -cnewer | Trova ciò il cui stato è cambiato dopo la modifica del file di riferimento | |
| -group | Filtra per nome del gruppo proprietario | |
| -xdev | Non scende nelle cartelle di altri file system | |
| -daystart | Calcola le condizioni di tempo dalle 0:00 di oggi invece che da 24 ore fa | |
| -prune | Se è una cartella, non vi scende | |
| -quit | Termina subito (-print -quit stampa solo il primo risultato) | |
| -printf | Stampa nel formato che stabilisci tu | |
| -ls | Stampa i file trovati in formato ls -dils | |
| -fprint | Salva i percorsi trovati in un file indicato invece che a schermo | |
| -ok | Esegue come -exec, ma chiede prima | |
| -execdir | Esegue come -exec, ma lancia il comando nella cartella del file trovato |
🔲 Simulatore del comando find
Il simulatore qui sotto è un server virtuale con la stessa cartella di prova, dove puoi eseguire condizioni come -name, -type, -size, -mtime e -perm, oltre a -exec e -delete.
7️⃣ Errori del comando find
Se scrivi un pattern senza virgolette, la shell applica le regole dei Caratteri jolly e lo espande prima nei nomi di file della cartella corrente. Andando nella cartella docs e scrivendo *.txt senza virgolette, la shell ha passato i due nomi guide.txt e readme.txt ed è comparso l'errore qui sotto.
cd /root/work/docsfind /root/work -name *.txtfind: paths must precede expression: `readme.txt'
find: possible unquoted pattern after predicate `-name'?Il codice di uscita era 1.
Senza \; o + alla fine di -exec è comparso [missing argument to `-exec’].
find /root/work -name '*.log' -exec ls -l {}find: missing argument to `-exec'Un percorso iniziale inesistente dà [No such file or directory] e termina con codice di uscita 1.
find /nonexistent-dir -name xfind: '/nonexistent-dir': No such file or directoryUn nome di account inesistente in -user, o un valore diverso dalle lettere previste come f e d in -type, termina subito con un errore senza iniziare la ricerca.
find /root/work -user nosuchuserfind: 'nosuchuser' is not the name of a known userfind /root/work -type xfind: Unknown argument to -type: xCon un account normale sul server Debian 12 abbiamo portato a 000 i permessi della cartella lock dentro la cartella di prova e poi cercato in quest'ultima. lock non era leggibile, è comparso [Permission denied] e il codice di uscita era 1.
find ~/findtest/home/user/findtest
/home/user/findtest/report.txt
/home/user/findtest/lock
find: '/home/user/findtest/lock': Permission denied
/home/user/findtest/docs
/home/user/findtest/docs/readme.txtPer nascondere solo le righe di errore, aggiungi 2>/dev/null. Il testo di errore è sparito, ma il codice di uscita è rimasto 1.
find ~/findtest -name '*.txt' 2>/dev/null/home/user/findtest/report.txt
/home/user/findtest/docs/readme.txt🔢 FAQ & contenuti consigliati
Ricerca nel contenuto
Comando grep di Linux
Un articolo sul comando grep, che trova testo nei file e stampa quelle righe, e sulle sue opzioni.
Eliminazione
Comando rm di Linux: opzioni di rm -rf e come eliminare senza conferma
Un articolo sulle opzioni -r e -f e sulle domande di conferma del comando rm per eliminare file e cartelle.
Spazio su disco
Comando du: controllare lo spazio su disco dei file
Un articolo su come sommare lo spazio su disco occupato da cartelle e file con il comando du.
ℹ️ Informativa sull'affiliazione
I contenuti di questo sito includono link di affiliazione. Se un visitatore acquista un prodotto o un servizio tramite uno di questi link, il sito riceve una commissione dal venditore. In questo processo l'importo pagato dall'acquirente (durante le promozioni l'importo scende↓) non aumenta. Prezzi, sconti e disponibilità indicati si riferiscono al momento della stesura e possono differire da quelli reali: prima di acquistare verifica sempre presso il venditore. I prodotti vengono scelti e valutati secondo criteri propri, e le commissioni non influiscono sull'ordine di presentazione né sul contenuto delle valutazioni.