TLDR: понять ваши корневые каталоги и настроить поиск оттуда, используя опцию -path <excluded_path> -prune -o
. Не включайте в конце исключенного пути трейлинг /
.
Пример:
find / -path /mnt -prune -o -name "*libname-server-2.a*" -print
Чтобы эффективно использовать find
, я считаю, что необходимо хорошо понимать структуру каталогов вашей файловой системы. На моем домашнем компьютере установлены жесткие диски с несколькими ТБ, резервная копия которых создается примерно для половины содержимого с использованием rsnapshot
(т.е. rsync
). Несмотря на то, что резервное копирование выполняется на физически независимый (дублирующий) диск, он монтируется в корневом системном каталоге (/
): /mnt/Backups/rsnapshot_backups/
:
/mnt/Backups/
└── rsnapshot_backups/
├── hourly.0/
├── hourly.1/
├── ...
├── daily.0/
├── daily.1/
├── ...
├── weekly.0/
├── weekly.1/
├── ...
├── monthly.0/
├── monthly.1/
└── ...
Каталог /mnt/Backups/rsnapshot_backups/
в настоящее время занимает ~ 2,9 ТБ, с ~ 60M файлами и папками; простой просмотр этого содержимого требует времени:
## As sudo (#), to avoid numerous "Permission denied" warnings:
# date; echo; \
time find /mnt/Backups/rsnapshot_backups | wc -l; echo; \
time du /mnt/Backups/rsnapshot_backups -d 0; echo; \
time rsnapshot du ## << more accurate re: rsnapshot footprint
Wed 22 May 2019 10:37:14 AM PDT
34:07.30 ## 34 min
60314138 ## 60.3M files, folders
3112240160 /mnt/Backups/rsnapshot_backups ## 3.1 TB
33:51.88 ## 34 min
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
Таким образом, в любое время, когда мне нужно найти файл в моем /
(корневом) разделе, мне нужно иметь дело (избегать, если это возможно) с обходом моего раздела резервных копий.
Примеры
Среди подходов, по-разному предложенных в этой теме ( Как исключить каталог из команды find. Команда ), я считаю, что поиск с использованием принятого ответа на намного быстрее - с оговорками .
Решение 1
Допустим, я хочу найти системный файл libname-server-2.a
, но я не хочу искать в моих rsnapshot
резервных копиях. Чтобы быстро найти системный файл, используйте исключающий путь /mnt
- , а не /mnt/
или /mnt/Backups
, ...):
## 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), with alternate timing mechanism,
## as 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!
... находит этот файл всего за несколько секунд, в то время как это занимает много дольше (кажется, что рекурсивно проходит через все "исключенные" каталоги):
## 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), with alternate timing mechanism,
## as 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
Раствор 2
Другое решение, предлагаемое в этой теме ( SO # 4210042 ), также работает плохо:
## 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
Резюме
В «Решении 1» (... -path <excluded_path> -prune -o ...
) кажется, что всякий раз, когда вы добавляете конечный /
, команда затем рекурсивно вводит (все эти) /mnt/*
каталоги - что в моем случае из-за /mnt/Backups/rsnapshot_backups/*
Подкаталоги, дополнительно включает в себя ~ 2,9 ТБ файлов для поиска! Не добавляя завершающий /
, поиск должен завершиться почти сразу (в течение нескольких секунд).
«Решение 2» (... -not -path <exclude path> ...
) также, по-видимому, рекурсивно ищет в исключенных каталогах, не возвращая эти попадания, но излишне тратя это время поиска.
Поиск в этих rsnapshot
резервных копиях:
Чтобы найти файл в одной из моих ежечасных / ежедневных / еженедельных / ежемесячных rsnapshot
резервных копий):
$ 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)
Исключая вложенный каталог:
Здесь я хочу исключить вложенный каталог, например, /mnt/Vancouver/projects/ie/claws/data/*
при поиске с /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
В сторону: Добавление -print
в конце команды подавляет распечатку исключенного каталога:
$ 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