TLDR: comprendere le directory di root e personalizzare la ricerca da lì, utilizzando l' -path <excluded_path> -prune -o
opzione. Non includere un finale/
alla fine del percorso escluso.
Esempio:
find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
Per utilizzare efficacemente find
credo che sia indispensabile avere una buona conoscenza della struttura della directory del file system. Sul mio computer di casa ho dischi rigidi multi-TB, con circa la metà del contenuto di cui è stato eseguito il backup utilizzando rsnapshot
(ad es rsync
.). Anche se il backup su un'unità fisicamente indipendente (duplicata), è montato nella /
directory root ( ) del mio sistema /mnt/Backups/rsnapshot_backups/
::
/mnt/Backups/
└── rsnapshot_backups/
├── hourly.0/
├── hourly.1/
├── ...
├── daily.0/
├── daily.1/
├── ...
├── weekly.0/
├── weekly.1/
├── ...
├── monthly.0/
├── monthly.1/
└── ...
La /mnt/Backups/rsnapshot_backups/
directory occupa attualmente ~ 2,9 TB, con ~ 60M file e cartelle; attraversare semplicemente quei contenuti richiede tempo:
## As sudo (#), to avoid numerous "Permission denied" warnings:
time find /mnt/Backups/rsnapshot_backups | wc -l
60314138 ## 60.3M files, folders
34:07.30 ## 34 min
time du /mnt/Backups/rsnapshot_backups -d 0
3112240160 /mnt/Backups/rsnapshot_backups ## 3.1 TB
33:51.88 ## 34 min
time rsnapshot du ## << more accurate re: rsnapshot footprint
2.9T /mnt/Backups/rsnapshot_backups/hourly.0/
4.1G /mnt/Backups/rsnapshot_backups/hourly.1/
...
4.7G /mnt/Backups/rsnapshot_backups/weekly.3/
2.9T total ## 2.9 TB, per sudo rsnapshot du (more accurate)
2:34:54 ## 2 hr 35 min
Pertanto, ogni volta che devo cercare un file sulla mia /
partizione (root), devo occuparmi di (evitare se possibile) attraversando la mia partizione di backup.
ESEMPI
Tra gli approcci variamente suggeriti in questo thread ( Come escludere una directory nel comando find. ), Trovo che le ricerche usando la risposta accettata siano molto più veloci - con avvertimenti.
Soluzione 1
Diciamo che voglio trovare il file di sistema libname-server-2.a
, ma non voglio cercare tra i miei rsnapshot
backup. Per trovare rapidamente un file di sistema, utilizzare il percorso exclude /mnt
(ovvero, use /mnt
, not /mnt/
, oppure /mnt/Backups
, o ...):
## As sudo (#), to avoid numerous "Permission denied" warnings:
time find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a
real 0m8.644s ## 8.6 sec <<< NOTE!
user 0m1.669s
sys 0m2.466s
## As regular user (victoria); I also use an alternate timing mechanism, as
## here I am using 2>/dev/null to suppress "Permission denied" warnings:
$ START="$(date +"%s")" && find 2>/dev/null / -path /mnt -prune -o \
-name "*libname-server-2.a*" -print; END="$(date +"%s")"; \
TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/usr/lib/libname-server-2.a
find command took 3 sec ## ~3 sec <<< NOTE!
... trova quel file in pochi secondi, mentre questo richiede molto più tempo (sembra ricorrere a tutte le directory "escluse"):
## As sudo (#), to avoid numerous "Permission denied" warnings:
time find / -path /mnt/ -prune -o -name "*libname-server-2.a*" -print
find: warning: -path /mnt/ will not match anything because it ends with /.
/usr/lib/libname-server-2.a
real 33m10.658s ## 33 min 11 sec (~231-663x slower!)
user 1m43.142s
sys 2m22.666s
## As regular user (victoria); I also use an alternate timing mechanism, as
## here I am using 2>/dev/null to suppress "Permission denied" warnings:
$ START="$(date +"%s")" && find 2>/dev/null / -path /mnt/ -prune -o \
-name "*libname-server-2.a*" -print; END="$(date +"%s")"; \
TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/usr/lib/libname-server-2.a
find command took 1775 sec ## 29.6 min
Soluzione 2
Anche l'altra soluzione offerta in questo thread ( SO # 4210042 ) ha prestazioni scarse:
## As sudo (#), to avoid numerous "Permission denied" warnings:
time find / -name "*libname-server-2.a*" -not -path "/mnt"
/usr/lib/libname-server-2.a
real 33m37.911s ## 33 min 38 sec (~235x slower)
user 1m45.134s
sys 2m31.846s
time find / -name "*libname-server-2.a*" -not -path "/mnt/*"
/usr/lib/libname-server-2.a
real 33m11.208s ## 33 min 11 sec
user 1m22.185s
sys 2m29.962s
SINTESI | CONCLUSIONI
Utilizzare l'approccio illustrato in " Soluzione 1 "
find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
vale a dire
... -path <excluded_path> -prune -o ...
notando che ogni volta che aggiungi il trailing /
al percorso escluso, il find
comando quindi inserisce ricorsivamente (tutte quelle) /mnt/*
directory - che nel mio caso, a causa delle /mnt/Backups/rsnapshot_backups/*
sottodirectory, include anche ~ 2,9 TB di file da cercare! Non aggiungendo un finale/
la ricerca dovrebbe essere completata quasi immediatamente (in pochi secondi).
Anche la "Soluzione 2" ( ... -not -path <exclude path> ...
) sembra cercare ricorsivamente tra le directory escluse - non restituendo le corrispondenze escluse, ma consumando inutilmente quel tempo di ricerca.
Ricerca all'interno di quei rsnapshot
backup:
Per trovare un file in uno dei miei rsnapshot
backup orari / giornalieri / settimanali / mensili ):
$ START="$(date +"%s")" && find 2>/dev/null /mnt/Backups/rsnapshot_backups/daily.0 -name '*04t8ugijrlkj.jpg'; END="$(date +"%s")"; TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/mnt/Backups/rsnapshot_backups/daily.0/snapshot_root/mnt/Vancouver/temp/04t8ugijrlkj.jpg
find command took 312 sec ## 5.2 minutes: despite apparent rsnapshot size
## (~4 GB), it is in fact searching through ~2.9 TB)
Escludendo una directory nidificata:
Qui, voglio escludere una directory nidificata, ad esempio /mnt/Vancouver/projects/ie/claws/data/*
durante la ricerca da /mnt/Vancouver/projects/
:
$ time find . -iname '*test_file*'
./ie/claws/data/test_file
./ie/claws/test_file
0:01.97
$ time find . -path '*/data' -prune -o -iname '*test_file*' -print
./ie/claws/test_file
0:00.07
A parte: l' aggiunta -print
alla fine del comando elimina la stampa della directory esclusa:
$ find / -path /mnt -prune -o -name "*libname-server-2.a*"
/mnt
/usr/lib/libname-server-2.a
$ find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a