TGViewer
Bash Days | Linux | DevOps Bash Days | Linux | DevOps @bashdays · 23.6K subscribers
Post #105 10.2K
В прошлом посте я затронул тему с 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 +++

То есть с опцией -q, grep не стал читать полностью весь гигабайтный файл, а сделал лишь один системный вызов read(3</tmp/large) и тут же завершил работу. Искомая строка нашлась, вернулся статус 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 и прекратит свою работу, как только найдет первое совпадение.

Вроде не сложно рассказал, по крайней мере попытался. Ладно, рад всех видеть, побежал дальше работу работать, сумасшедший какой-то день. Пока пока!

tags: #linux #bash #debug
—
💩 @bashdays
  • 👍 95
More from @bashdays
  1. Sep 29, 2026Самый жаркий холивар в команде — это не systemd, а какие заказать роллы на всю команду. Од…
  2. Sep 24, 2026Post #1565
  3. Sep 23, 2026Здрасти приехали, решил я в кой-то веке воспользоваться услугами Codex, создал аккаунт, по…
  4. Sep 22, 2026Всем привет, с вами TagdTagd. Сегодня опять поднимем тему архивов, но немного с другой сто…
  5. Sep 15, 2026Всем привет, с вами TagdTagd. И это вторая часть. Практическая. С первой частью можешь озн…
  6. Sep 9, 2026Всем привет, с вами TagdTagd! Я тут вынужденно перешёл на MAX. Просто Telegram перестал ра…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →