Битлента
Сетевые команды и утилиты5 мин чтения·

grep и ss: как отфильтровать соединения по состоянию и порту

Как оставить в выводе ss или netstat только нужные строки: ESTAB, LISTEN, порт 443, один адрес. Ключи grep -c, -v, -E, -w и типичные ошибки.

Кратко

Вывод ss или netstat удобно пропускать через grep: ss -tan | grep ESTAB оставит установленные соединения, grep -c даст их число, grep -v уберёт лишнее. Порт ищите с двоеточием и границей справа, например grep -E ':443( |$)', иначе подстрока зацепит чужие строки.

Почему вывод ss приходится фильтровать руками

Команда ss -tan на рабочей машине легко выдаёт десятки и сотни строк: браузер держит соединения с разными серверами, мессенджер и синхронизация файлов добавляют свои. Искать глазами нужный порт или адрес в такой простыне неудобно, и именно здесь выручает grep. Он читает поток построчно и пропускает только те строки, где нашлось совпадение с шаблоном.

У самой ss есть встроенные фильтры, например ss -tan state established, и они хороши, когда нужно одно состояние. Но стоит захотеть «установленные соединения с портом 443, кроме локальных», как проще собрать цепочку из нескольких простых команд, чем вспоминать синтаксис выражений ss. Конвейер читается слева направо, и каждый шаг можно проверить отдельно, убрав всё после него.

Дальше примеры на ss, потому что эта утилита есть в большинстве дистрибутивов Linux. В macOS её обычно нет, там те же приёмы работают с выводом netstat -an: меняется только написание состояний.

Как состояния называются в выводе

Первая ловушка: шаблон для grep зависит от того, какая утилита породила текст. В выводе ss состояния пишутся сокращённо, а в netstat полностью и с подчёркиванием. Если искать ESTABLISHED в выводе ss, не найдётся ни одной строки, и можно решить, что соединений нет.

СостояниеВ выводе ssВ выводе netstat
Соединение установленоESTABESTABLISHED
Порт слушаетLISTENLISTEN
Ожидание после закрытияTIME-WAITTIME_WAIT
Ждёт закрытия приложениемCLOSE-WAITCLOSE_WAIT
Отправлен SYN, ответа нетSYN-SENTSYN_SENT

Чтобы не гадать, один раз выведите полный список и посмотрите на первый столбец. Если сомневаетесь в написании, шаблон можно сделать мягче: grep -i estab найдёт и ESTAB, и ESTABLISHED, независимо от регистра.

Ключи grep, которых хватает в большинстве случаев

Для работы с выводом сетевых команд обычно достаточно нескольких ключей. Их полезно знать наизусть, потому что дальше они комбинируются.

  • -i игнорирует регистр букв в шаблоне.
  • -v инвертирует выбор: остаются строки, где совпадения нет.
  • -c печатает только число подходящих строк вместо самих строк.
  • -n добавляет номер строки перед каждым совпадением.
  • -w ищет шаблон как целое слово, а не как кусок слова.
  • -E включает расширенные регулярные выражения: скобки, вертикальную черту, плюс.
  • -F читает шаблон как обычный текст без спецсимволов, что удобно для адресов с точками.
  • -o печатает только совпавшую часть строки, а не всю строку.

Ключи можно склеивать: grep -ci estab считает строки без учёта регистра. Для остальных ключей, включая вывод строк контекста до и после совпадения, смотрите справку grep или man grep: набор опций немного различается между GNU grep и версией, которая идёт с macOS.

🛡️ Остались проблемы с соединением?
Можно пользоваться постоянно: российские приложения работают, включать и выключать ничего не нужно. Без карты и регистрации, настройка за пару минут.
Попробовать бесплатно

Готовые примеры на выводе ss -tan

Ниже рабочие цепочки. Адреса из блоков документации 192.0.2.0/24 и 198.51.100.0/24 здесь взяты как условные.

  1. ss -tan | grep ESTAB — только установленные соединения.
  2. ss -tan | grep -c ESTAB — сколько их, одним числом.
  3. ss -tan | grep LISTEN — какие порты принимают входящие подключения.
  4. ss -tan | grep ESTAB | grep -E ':443( |$)' — установленные соединения с портом 443: после номера должен идти пробел или конец строки.
  5. ss -tan | grep -E ':(80|443)( |$)' — порты 80 и 443 одним шаблоном.
  6. ss -tan | grep ESTAB | grep -v '127.0.0.1' — без локальных соединений самого компьютера по адресу 127.0.0.1 (IPv6-адрес ::1 так не отсеять).
  7. ss -tan | grep -F '198.51.100.7' — все строки, где встречается один адрес.

Пример строки условный, у вас формат может отличаться. Строка вывода выглядит примерно так: ESTAB 0 0 192.0.2.10:52144 198.51.100.7:443. Слева локальный адрес с портом, справа удалённый. Если нужен только порт или только адрес, а не вся строка, grep уже неудобен: для вырезания столбцов лучше подойдёт awk, об этом отдельная страница.

Где grep вводит в заблуждение

Распространённая причина странных результатов — подстрока. Шаблон :443 совпадёт и с портом 443, и с портом 4430, и с хвостом IPv6-адреса. Поэтому перед номером порта ставят двоеточие, которое отделяет его от адреса, а после номера требуют пробел или конец строки: ':443( |$)'. Просто пробел в конце шаблона не подходит, потому что удалённый порт в ss стоит последним в строке, и после него пробела нет. С IPv6 строки получаются длиннее и с большим числом двоеточий, так что проверяйте результат глазами хотя бы на одном примере.

Вторая особенность: заголовок таблицы тоже строка. Если вы считаете строки без grep, например через wc -l, к итогу добавится одна лишняя строка с названиями столбцов. Шаблон ESTAB заголовок не захватит, поэтому счёт через grep -c получается точнее.

Третья: код возврата. Когда ни одна строка не подошла, grep завершается с кодом 1, и в скриптах с проверкой ошибок это выглядит как сбой, хотя команда отработала штатно. Наконец, сам grep иногда попадает в вывод ps, если вы ищете процесс, но к ss это не относится.

Если результат выглядит неправдоподобно, уберите последнее звено цепочки и посмотрите на вывод до него: так проще понять, на каком шаге строки пропали.

Как собрать фильтр под свою задачу

Удобный порядок такой: сначала посмотреть сырой вывод и найти в нём строку, которая нужна, потом добавлять по одному звену. Каждое звено сужает выбор, и по числу оставшихся строк видно, что именно отсеялось.

Например, нужно понять, сколько соединений держит один адрес. Сначала выполните ss -tan | grep -F '198.51.100.7' и убедитесь, что адрес вообще встречается. Затем допишите | grep -c ESTAB и сравните число с количеством строк без второго фильтра. Разница покажет соединения в других состояниях, например TIME-WAIT: они уже закрыты и просто доживают положенное время.

Кавычки вокруг шаблона нужны, когда в нём есть пробел, точка с запятой, скобки или вертикальная черта: оболочка иначе попытается истолковать их по-своему. Одинарные кавычки защищают шаблон надёжнее двойных, потому что внутри них оболочка ничего не подставляет.

Если нужно повторять проверку каждую секунду, цепочку целиком можно отдать команде watch, а для долгого наблюдения за файлом журнала подходит tail -f. Обе команды разобраны на отдельных страницах этого раздела.

🛡️ Остались проблемы с соединением?
Можно пользоваться постоянно: российские приложения работают, включать и выключать ничего не нужно. Без карты и регистрации, настройка за пару минут.
Попробовать бесплатно
grepsslinuxфильтрация вывода

Часто задаваемые вопросы

Читайте также