Каковы точные причины `grep` на / proc и raw дисках - плохая идея?

9

Я побежал grep -r "searchphrase" /сегодня, и это не сработало. Я провел некоторое исследование и нашел find / -xdev -type f -print0 | xargs -0 grep -H "searchphrase"правильный подход.

Я собираю /procи диски, как /dev/sda1виновники неудачного grep.

Я хотел бы иметь глубокие технические знания о "почему". Я думаю, что некоторые ссылки внутри /procсоздают бесконечные циклы при прохождении, и я прочитал, что есть больше причин, но ничего конкретного.

Кроме того, что происходит, когда очищается необработанный диск? Разве двоичные данные (которые доступны /dev/sda1, насколько я знаю?) Не могут быть интерпретированы, поскольку только данные mountс файловой системой делают данные с диска понятными? Следовательно, можно ли использовать grep для двоичной строки?

curious_weather
источник

Ответы:

11

Да, вы можете grep /dev/sda1и , /procно вы , вероятно , не хотите. Более детально:

  1. Да, вы можете запустить grep двоичное содержимое /dev/sda1. Но с современными большими жесткими дисками это займет очень много времени, и результат вряд ли будет полезным.

  2. Да, вы можете просматривать содержимое, /procно помните, что память вашего компьютера там отображается в виде файлов. На современном компьютере с гигабайтами оперативной памяти это займет много времени, и, опять же, результат вряд ли будет полезным.

В качестве исключения, если вы ищете данные на жестком диске с поврежденной файловой системой, вы можете запустить grep something /dev/sda1как часть попытки восстановить данные файла.

Другие проблемные файлы в /dev

Жесткие диски и разделы жесткого диска /devмогут быть, если у вас хватит терпения, нарезаться. Другие файлы ( шляпный совет: user2313067 ), однако, могут вызвать проблемы:

  1. /dev/zeroэто файл бесконечной длины. К счастью, grep(по крайней мере, версия GNU) достаточно умен, чтобы пропустить это:

    $ grep something /dev/zero
    grep: input is too large to count
    
  2. /dev/randomи /dev/urandomтакже бесконечны. Команда grep something /dev/randomбудет выполняться вечно, пока не grepбудет дано предупреждение об остановке.

    Это может быть полезно для grep /dev/urandomпри генерации паролей. Чтобы получить, например, пять случайных буквенно-цифровых символов:

    $ grep --text -o '[[:alnum:]]' /dev/urandom | head -c 10
    G
    4
    n
    X
    2
    

    Это не бесконечно, потому что, после получения достаточного количества символов, headканал закрывается, что приводит к завершению grep.

Бесконечные циклы

"... ссылки ... создают бесконечные циклы при прохождении ..."

Grep (по крайней мере, версия GNU) достаточно умен, чтобы этого не делать. Давайте рассмотрим два случая:

  1. С этой -rопцией grep не следует по символическим ссылкам, если они явно не указаны в командной строке. Следовательно, бесконечные циклы невозможны.

  2. С -Rопцией, Grep делает следовать символическим ссылкам , но он проверяет их и отказывается попасть в петле. Проиллюстрировать:

    $ mkdir a
    $ ln -s ../ a/b
    $ grep -R something .
    grep: warning: ./a/b: recursive directory loop
    

Исключая проблемные каталоги из grep -r

Кроме того, grepпредоставляет ограниченное средство, чтобы остановить поиск grep определенных файлов или каталогов. Например, можно исключить все каталоги по имени proc, sysи devот рекурсивного поиска Grep с:

grep --exclude-dir proc --exclude-dir sys --exclude-dir dev -r something /

С другой стороны , мы можем исключить proc, sysи devиспользуя расширенные шарики в Bash:

shopt -s extglob
grep -r something /!(proc|sys|dev)
John1024
источник
Спасибо! Это отличный ответ. Если сегодня вечером из темноты не выйдет другой герой, я приму это завтра! Меня интересует еще одна вещь, и я надеюсь, что это не так уж и далеко: если grepпоиск в файле /procприводит к отображению памяти, может ли случиться так, что он grepпопадет в EOF внутри (случайной) памяти и интерпретирует следующие данные как новое имя файла для поиска? Я начал читать grepисходный код, но я думаю, я не буду видеть в нем слишком много.
curious_weather
1
@krork В некоторых старых операционных системах, таких как CP / M, конец файла обозначался символом EOF. Поскольку современные файловые системы отслеживают размер файла, такие символы перестали использоваться.
John1024
2
Grepping /devможет никогда не закончиться, так как grep начинает сканировать /dev/zeroили что-то подобное. Не уверены, что такие файлы существуют в /procили /sys.
user2313067 14.10.16
1
@ user2313067 Хороший вопрос! В то время как GNU grep откажется от поиска /dev/zero, он будет искать /dev/randomвечно, пока не будет остановлен. Ответ обновлен.
John1024
Я ничего не делаю с / proc или / sys, но так как это виртуальные каталоги, которые могут обновляться в любое время, вы можете получить неожиданные / неповторимые результаты от нескольких запусков. Конечно, это может происходить и с обычными файловыми системами, но это может быть немного более удивительным.
Джо