`grep` для всех файлов для строки занимает много времени
grep
параметры команды
Я хотел обыскать весь мой диск на предмет наличия строки. После принятого ответа в Stack Overflow я использовал:
sudo time grep -rnw '/' -e 'Sony 50"'
и потребовалось 53 часа для обработки 20 ГБ данных на одном из самых быстрых SSD-накопителей PCIe NVMe M.2; Samsung Pro 960.
grep
выходной журнал
когда grep
обрабатывает некоторые файлы, генерирует сообщения об ошибках. Они могут быть подавлены путем добавления 2>/dev/null
в команду. Однако ошибки дают обратную связь о достигнутом прогрессе. Некоторые из выходных данных примера (это не будет все соответствовать) ниже:
Binary file /home/Me/.config/google-chrome/Default/Sync Data/SyncData.sqlite3 matches
grep: /sys/kernel/security/ima/policy: Permission denied
grep: /sys/kernel/slab/:dt-0000008/alloc_calls: Function not implemented
grep: /sys/kernel/slab/:dt-0000008/free_calls: Function not implemented
(... SNIP ... 12 hours later PID 882 processed below...)
grep: /proc/882/task/922/attr/sockcreate: Invalid argument
grep: /proc/882/task/923/mem: Input/output error
(... SNIP ... 24 hours later PID 2954 below...)
grep: /proc/2598/attr/sockcreate: Invalid argument
grep: /proc/2954/task/2954/mem: Input/output error
(... SNIP ... 42 hours later PID 4396 below...)
grep: /proc/4389/attr/sockcreate: Invalid argument
grep: /proc/4396/task/4396/mem: Input/output error
(... SNIP ... After 53 hours `grep` finally finishes...)
grep: /run/user/1000/gvfs: Permission denied
Command exited with non-zero status 2
97355.34user 83223.12system 53:07:40elapsed 94%CPU (0avgtext+0avgdata 31116maxresident)k
593910020inputs+0outputs (1major+10731minor)pagefaults 0swaps
grep
создается впечатление, что он заморожен
Иногда я думал grep
был заморожен, потому что экран не обновлялся в течение часа, а индикатор жесткого диска не мигал. Однако Конки говорит мне, что он все еще работает и использует 100% ЦП на одном ядре, как показано в этом GIF.
Из 19,5 ГБ из 43,8 ГБ, используемых в разделе Linux (Ubuntu 16.04.3 LTS), половина этого пространства, 10 ГБ, используется ядрами. Загрузка и тестирование ядер - мое время.
Этот тест занял большую часть моего уик-энда плюс понедельник.
Как я могу ускорить grep
и все еще получить то, что я ищу?
2 ответа
Исключить виртуальные файловые системы
Глядя на пример выходного журнала, мы видим, что виртуальные файловые системы включены в поиск, что является ненужной тратой времени. Удалите эти и другие каталоги из поиска с помощью --exclude-dir
вариант. Например:
sudo time grep -rnw --exclude-dir={boot,dev,lib,media,mnt,proc,root,run,sys,/tmp,tmpfs,var} '/' -e 'Sony 50"'
когда grep
разбирает /proc
Цепочка каталогов бесполезно просматривает все идентификаторы процессов, что в моем случае занимает больше суток.
Также при обработке /mnt
он будет смотреть на подключенные диски Windows NTFS и USB без необходимости.
/media
Он содержит дисковод CD/DVD и внешние USB-накопители.
Выход:
$ sudo time grep -rnw --exclude-dir={boot,dev,lib,media,mnt,proc,root,run,sys,/tmp,tmpfs,var} '/' -e 'Sony 50"'
Binary file /home/Me/.config/google-chrome/Default/Sync Data/SyncData.sqlite3 matches
11.35user 13.83system 0:56.35elapsed 44%CPU (0avgtext+0avgdata 8480maxresident)k
17369032inputs+0outputs (0major+1620minor)pagefaults 0swaps
Там вы идете 56 секунд вместо 50 часов!
Обратите внимание, если вы исключите usr
(содержит 6,5 ГБ файлов в моем случае) из поиска это всего 8 секунд:
4.48user 1.80system 0:08.75elapsed 71%CPU (0avgtext+0avgdata 6012maxresident)k
13008964inputs+0outputs (0major+1180minor)pagefaults 0swaps
Интересные заметки
Хранение системных каталогов, кажется, сохраняет grep
на лучшем треке, и он никогда не достигает 100% CPU на одном ядре. Кроме того, индикатор жесткого диска постоянно мигает, чтобы вы знали, grep
действительно работает, а не "думать по кругу".
Если вы не префикс tmp
с /
тогда он будет игнорировать любой подкаталог, содержащий tmp
например /home/Me/tmp
, Если вы используете --exclude-dir /tmp
тогда ваш каталог /home/Me/tmp
будет произведен поиск
Если с другой стороны вы префикс sys
с /
тогда тогда /sys
каталог ищется и сообщается об ошибках. То же самое верно для /proc
, Так что вы должны использовать sys,proc
и не префикс их /
, То же самое верно и для других системных каталогов, которые я тестировал.
Создать псевдоним grepall
Рассмотрите возможность создания псевдонима в ~/.bashrc
так что вам не нужно вводить --exclude-dir
список параметров каждый раз:
alias grepall="grep --exclude-dir={boot,dev,lib,media,mnt,proc,root,run,sys,/tmp,tmpfs,var}"
Подробная разбивка по времени
В этом разделе показано, сколько времени сэкономлено, путем постепенного добавления каталогов в --exclude-dir
список параметров:
/proc
а также/sys
экономя 52 часа/media
экономия 3 минуты/mnt
экономия 21 минут/usr/src
(указавsrc
) экономия 53 секунд/lib/modules
(указавmodules
) экономия 39 секунд
исключать /proc
а также /sys
каталоги
/proc
а также /sys
каталоги являются самыми трудоемкими, наиболее бесполезными для поиска и генерации большинства ошибок. Это "бесполезно", потому что эти два каталога динамически создаются во время выполнения и не содержат постоянных файлов, которые вы хотели бы grep
,
Большая экономия времени достигается за счет исключения их:
$ sudo time grep -rnw --exclude-dir={proc,sys} '/' -e 'Garbage 098jfsd'
/var/log/auth.log:4653:Feb 16 17:46:20 alien sudo: rick : TTY=pts/18 ; PWD=/home/rick/Downloads ; USER=root ; COMMAND=/usr/bin/time grep -rnw --exclude-dir=proc --exclude-dir=sys / -e Garbage 098jfsd
Binary file /var/log/journal/d7b25a27fe064cadb75a2f2f6ca7764e/system.journal matches
grep: /media/rick/S3A6550D005/hiberfil.sys: Input/output error
(... SNIP ...)
grep: /media/rick/S3A6550D005/winproductkey: Input/output error
grep: /run/user/1000/gvfs: Permission denied
Command exited with non-zero status 2
422.43user 112.91system 26:59.03elapsed 33%CPU (0avgtext+0avgdata 31152maxresident)k
379671064inputs+0outputs (1major+10738minor)pagefaults 0swaps
Только 27 минут, экономя более 52 часов!
Есть еще ошибки, хотя. В /var
каталог, который также является "виртуальным каталогом", созданным во время выполнения. /run
каталог, который содержит мобильный телефон Android и /media
каталог, в котором находится старый сломанный жесткий диск ноутбука, теперь подключенный к внешнему жесткому диску USB.
добавлять /media
исключить список
/media
каталог содержит старый ноутбук, подключенный через порт USB 3.0. Smartctl ежедневно сообщает об ошибках на диске и не имеет файлов, которые мы ищем. Мы исключим это, чтобы сэкономить время и уменьшить количество сообщений об ошибках:
$ sudo time grep -rnw --exclude-dir={proc,sys,media} '/' -e 'Garbage 654asdf'
/var/log/auth.log:4664:Feb 16 18:26:27 alien sudo: rick : TTY=pts/18 ; PWD=/home/rick/Downloads ; USER=root ; COMMAND=/usr/bin/time grep -rnw --exclude-dir=proc --exclude-dir=sys --exclude-dir=media / -e Garbage 654asdf
Binary file /var/log/journal/d7b25a27fe064cadb75a2f2f6ca7764e/system.journal matches
grep: /run/user/1000/gvfs: Permission denied
Command exited with non-zero status 2
405.51user 105.38system 23:26.89elapsed 36%CPU (0avgtext+0avgdata 30908maxresident)k
365800875inputs+0outputs (0major+10961minor)pagefaults 0swaps
Исключая неисправный жесткий диск, подключенный через корпус USB 3.0, вы сэкономили всего 3 минуты, но сократили количество сообщений об ошибках.
добавлять /mnt
(Разделы Windows NTFS), чтобы исключить список
/mnt
каталог содержит:
- Два раздела NTFS для Windows 10 (
C:
а такжеE:
) на SSD с 105 ГиБ данных - Один раздел NTFS для Windows 10 (
D:
) на жестком диске с 42 ГиБ данных
В Windows нет ничего интересного, поэтому мы исключим /mnt
экономить время:
$ ll /mnt
total 44
drwxr-xr-x 5 root root 4096 Nov 12 07:19 ./
drwxr-xr-x 27 root root 4096 Feb 15 20:43 ../
drwxrwxrwx 1 root root 8192 Dec 30 14:00 c/
drwxrwxrwx 1 root root 8192 Dec 30 14:31 d/
drwxrwxrwx 1 root root 20480 Jan 1 13:22 e/
$ sudo time grep -rnw --exclude-dir={proc,sys,media,mnt} '/' -e 'Garbage zx5cv7er'
/var/log/auth.log:5093:Feb 17 10:31:44 alien sudo: rick : TTY=pts/18 ; PWD=/home/rick/Downloads ; USER=root ; COMMAND=/usr/bin/time grep -rnw --exclude-dir=proc --exclude-dir=sys --exclude-dir=media --exclude-dir=mnt / -e Garbage zx5cv7er
Binary file /var/log/journal/d7b25a27fe064cadb75a2f2f6ca7764e/system.journal matches
grep: /run/user/1000/gvfs: Permission denied
Command exited with non-zero status 2
51.50user 23.28system 2:08.85elapsed 58%CPU (0avgtext+0avgdata 15800maxresident)k
39866258inputs+0outputs (0major+6059minor)pagefaults 0swaps
Сейчас grep
занимает всего 2 минуты и 8 секунд. Исключение разделов Windows 10 с 147 Gib программ и данных экономит 21,5 минут!
добавлять /usr/src
Заголовки Linux, чтобы исключить список
/usr/src
каталог содержит исходный код заголовков Linux. В моем случае вручную установлено более 20 ядер, что занимает много места. Чтобы указать каталог, хотя используемый аргумент src
:
$ du -h -s /usr/src
3.2G /usr/src
$ sudo time grep -rnw --exclude-dir={proc,sys,media,mnt,src} '/' -e 'Garbage z5cv7er'
/var/log/auth.log:5096:Feb 17 10:34:28 alien sudo: rick : TTY=pts/18 ; PWD=/home/rick/Downloads ; USER=root ; COMMAND=/usr/bin/time grep -rnw --exclude-dir=proc --exclude-dir=sys --exclude-dir=media --exclude-dir=mnt --exclude-dir=src / -e Garbage z5cv7er
Binary file /var/log/journal/d7b25a27fe064cadb75a2f2f6ca7764e/system.journal matches
grep: /run/user/1000/gvfs: Permission denied
Command exited with non-zero status 2
44.21user 8.54system 1:15.51elapsed 69%CPU (0avgtext+0avgdata 15864maxresident)k
33754180inputs+0outputs (0major+6062minor)pagefaults 0swaps
Теперь grep занимает всего 1 минуту и 15 секунд. Исключая /usr/src
указав src
на --exclude-dir
список экономит 53 секунды.
добавлять /lib/modules
Модули ядра для исключения списка
/lib/modules
каталог содержит скомпилированные модули ядра. Чтобы указать каталог, хотя используемый аргумент modules
:
$ du -h -d1 /lib/modules
285M /lib/modules/4.14.18-041418-generic
282M /lib/modules/4.14.14-041414-generic
(... SNIP ...)
228M /lib/modules/4.9.76-040976-generic
6.0G /lib/modules
$ sudo time grep -rnw --exclude-dir={proc,sys,media,mnt,src,modules} '/' -e 'Garbage 1cv7fer'
/var/log/auth.log:5117:Feb 17 11:07:41 alien sudo: rick : TTY=pts/18 ; PWD=/home/rick/Downloads ; USER=root ; COMMAND=/usr/bin/time grep -rnw --exclude-dir=proc --exclude-dir=sys --exclude-dir=media --exclude-dir=mnt --exclude-dir=src --exclude-dir=modules / -e Garbage 1cv7fer
Binary file /var/log/journal/d7b25a27fe064cadb75a2f2f6ca7764e/system.journal matches
grep: /run/user/1000/gvfs: Permission denied
Command exited with non-zero status 2
19.22user 5.84system 0:35.61elapsed 70%CPU (0avgtext+0avgdata 15600maxresident)k
22111388inputs+0outputs (0major+6059minor)pagefaults 0swaps
Пропустив 6 ГБ модулей ядра, наш grep
время 36 секунд. Добавление /lib/modules
указав modules
в --exclude-dir
Параметр экономит 39 секунд.
Разные каталоги
Сводный список других каталогов:
- / boot экономит 3 секунды (но мой очень большой)
- / dev экономит 3 секунды
- / запустить экономит 4 секунды
- / Var экономит 8 секунд
После принятого ответа:
grep -nrilIF --exclude-dir={boot,dev,lib,media,mnt,proc,root,run,sys,/tmp,tmpfs,var} / -e "search term" 2>/dev/null
в частности -I : обрабатывать двоичный файл так, как если бы он не содержал совпадающих данных, -F : интерпретировать ШАБЛОНЫ как фиксированные строки, а не регулярные выражения с -e (регулярное выражение), по-прежнему требуется указать фиксированную строку для поиска