Я думаю, що ви хочете зробити, це отримати список портів прослуховування, а потім видалити їх з будь-яких інших підключень TCP, тоді це будуть всі вихідні з'єднання. Команда ss (статус сокета) виводить стовпці "Місцева адреса: порт" та "Адреса однорангової: порту", нам потрібно видалити порти прослуховування зі стовпця "Місцева адреса: Порт", а не стовпця "Peer Address: Port", інакше ви можете пропустити деякі вихідні з'єднання. Отже, щоб досягти того, що я використовую \s{2}+
рядок ": $ port" у грепі, щоб відповідати пробілам, що знаходяться за стовпцем "Локальна адреса: Порт"; у цьому стовпці є два або більше білих пробілів за ним, де в "Peer Address: Port" є один пробіл, а потім новий рядок (grrr ... просто повинен бути новий рядок, IMO,\s+
\s{2}+
.) Зазвичай я можу спробувати використовувати функцію фільтрації ss, наприклад, з ss -tn state established '(sport != :<port1> and sport !=:<port2>)' src <ip address>
. Але, схоже, існує обмеження щодо того, наскільки ця струна може бути, вона бомбардується в системі, де у мене було багато портів прослуховування. Тому я намагаюся зробити те ж саме з грепом. Я вважаю, що спрацює наступне:
FILTER=$(ss -tn state listening | gawk 'NR > 1 {n=split($3,A,":"); B[NR-1]=A[n]} END {for (i=1; i<length(B); i++) printf ":%s\\s{2}+|", B[i]; printf ":%s\\s{2}+", B[i]}')
ss -tn state established dst :* | grep -P -v "$FILTER"
Зауважте, це залежить від версії ss, яку ви використовуєте, старіші версії (наприклад: утиліта ss, iproute2-ss111117) мають інший вихідний формат, тому вам, можливо, доведеться використовувати $ 3 замість 4 доларів in awk. Зауважте також, ss -tln
і ss -tn state listening
ви отримуєте різні результати, що для мене трохи не інтуїтивно зрозуміло. YMMV.
Я знайшов трохи більш елегантне рішення, яке не вимагає знання IP-адреси хоста, ss -tn state established dst :*
працює добре, я змінив командні рядки вище.