В прошлом посте я затронул тему с grep, так вот. У grep есть хороший ключик -q. При указании этого ключа, утилита прекращает свою работу, как только нашлась заданная подстрока. Это правильная оптимизация и ей нужно пользоваться, если нужно проверить наличие подстроки в файле.
Давай попрактикуемся и с помощью strace посмотрим, как чо там в кишках происходит. Создаем большой файл и забиваем его рандомными данными:
head -c 1G /dev/urandom > /tmp/large
Если head не понимает буковку G в размере, то указываем явный размер файла: -c 1073741824
.
Так, файл размером 1G готов /tmp/large, дальше запускаем:
strace -P /tmp/large -ye read grep -q 's' /tmp/large
Ключи: -P = путь до файла -y = выводит имя пути до файла -e = команда которую дебажим
Через секунду, на выходе получаем нечто подобное:
read(3</tmp/large>, "v\310*A\307\16\324m&V8H\202\326\177\244\3059\27}00_\274\300<\245.X\27\310`"..., 98304) = 98304
+++ exited with 0 +++
Делаем то же самое без strace и проверяем статус выхода, все ли идентично:
grep -q 's' /tmp/large
echo $?
На выходе у нас будет 0. Ок, эксперимент завершился успехом. Некоторые версии grep могут возвращать истину если ошибка произошла, не связанная с поиском. Этот момент нужно учитывать. Про такие случаи хорошо написано здесь.
Если коротко, некоторые версии grep с ключом -q могут вернуть статус выхода 2. Так что на разных системах работать может по-разному. Если в своих скриптах проверяешь эти статусы, логика может сломаться, будь аккуратнее с этим.
Еще нюанс, можно добиться такого же поведения grep, но без ключа -q. Это сработает, если вывод перенаправлен в /dev/null. Ну это и логично, нам не нужен никакой вывод на экран и нет никакого смысла продолжать читать огромный файл если подстрока уже найдена.
strace -P /tmp/large -ye read grep 's' /tmp/large > /dev/null
Утилита grep (без ключа -q) также сделает один системный вызов read и прекратит свою работу, как только найдет первое совпадение.
Вроде несложно рассказал, по крайней мере попытался. Ладно, рад всех видеть, побежал дальше работу работать, сумасшедший какой-то день. Пока пока!








Комментарии