Linux команда получает неиспользуемый порт


20

Я ищу команду или скрипт, который возвращает неиспользуемый порт в моей системе Ubuntu Linux. Я смотрю в Интернете, и единственное, что я нахожу, - это порт used / Listen с помощью команды nestat. Очевидно, что-то с командой netstat будет работать, но не знаю, что именно. Есть идеи как?

Благодарю.



1
Почему вам нужно сделать это именно так? Если вы разрабатываете сервер, вы можете привязаться к порту 0, и ОС выделит вам свободный порт, вам нечего искать. В противном случае поиск, а затем связывание подвержены условиям гонки. См., Например, stackoverflow.com/questions/1365265/… или stackoverflow.com/questions/1075399/…
Патрик Мевзек,

Ответы:


14

netstat -latдает полный список прослушивания и установленных портов.

Когда порт не находится ни в одном из этих состояний, для системы не существует, поэтому вы не найдете команду, которая показывает список неиспользуемых портов.

Имейте в виду, что есть 65535 портов, поэтому все, что не включено, netstat -latявляется неиспользуемым портом.

Следующий скрипт bash выполнит простое сканирование портов TCP и сообщит, какие из них открыты, а какие закрыты :

#!/bin/bash
IP=$1
first_port=$2
last_port=$3
function scanner

{
for ((port=$first_port; port<=$last_port; port++))
        do
                (echo >/dev/tcp/$IP/$port)> /dev/null 2>&1 && echo $port open || echo "$port closed"
        done
}

scanner

Если вы сохраните его как portscan.sh, то он должен быть запущен как ./portscan.sh IP first_port last_port , например: ./portscan 127.0.0.1 20 135будет сканировать локальное оборудование с портов с 20 по 135


7

Ruby 2.x (однострочник):

ruby -e 'require "socket"; puts Addrinfo.tcp("", 0).bind {|s| s.local_address.ip_port }'

На моей машине прямо сейчас напечатано:

42644

Последующий вызов напечатан:

36168

Этот метод заставляет текущего пользователя запрашивать неиспользуемый порт (привязать к порту «0»), а затем распечатывает номер порта, предоставленный операционной системой. И поскольку текущий пользователь задает вопрос, порты ниже 1024 не будут возвращены (если текущий пользователь = root).

Кредит, где кредит должен - это решение взято из комментария Фрэнклина Ю на unix.stackexchange.com. Какой самый простой способ найти неиспользуемый локальный порт?


Как я могу присвоить результат этого переменной в сценарии bash?
Нил Стивенс

PORT экспорта = $ (ruby -e 'требует "сокета"; помещает Addrinfo.tcp ("", 0) .bind {| s | s.local_address.ip_port}')
Г. Сильви Дэвис

3

Короткий сценарий bash, который случайным образом генерирует число от 1025 до 60000 и циклически повторяется, пока это число не будет найдено в списке используемых портов. Это быстрое и грязное решение, которое имеет тенденцию к большим портам:

CHECK="do while"

while [[ ! -z $CHECK ]]; do
    PORT=$(( ( RANDOM % 60000 )  + 1025 ))
    CHECK=$(sudo netstat -ap | grep $PORT)
done

echo $PORT

Проверьте вашу команду grep, смотрите комментарий к ответу adarshr
Ник

2

Один лайнер

Я собрал хороший однострочный текст, который быстро служит цели, позволяя захватывать произвольное количество портов в произвольном диапазоне (здесь он разделен на 4 строки для удобства чтения):

comm -23 \
<(seq "$FROM" "$TO") \
<(ss -tan | awk '{print $4}' | cut -d':' -f2 | grep '[0-9]\{1,5\}' | sort -n | uniq) \
| shuf | head -n "$HOWMANY"

Построчно

commутилита, которая сравнивает отсортированные строки в двух файлах Он выводит три столбца: строки, которые появляются только в первом файле, строки, которые появляются только во втором файле, и общие строки. Указывая, -23мы подавляем последние столбцы и оставляем только первый. Мы можем использовать это, чтобы получить разницу двух наборов, выраженную в виде последовательности текстовых строк. Я узнал об этом comm здесь .

Первый файл - это диапазон портов, из которых мы можем выбирать. seqпроизводит отсортированную последовательность чисел от $FROMдо $TO. Результат передается в commкачестве первого файла с использованием подстановки процесса .

Второй файл - это отсортированный список портов, который мы получаем, вызывая ssкоманду (что -tозначает TCP-порты, то -aесть все установленные и прослушиваемые - и -nчисловые - не пытайтесь разрешить, скажем, 22к ssh). Затем мы выбираем только четвертый столбец с awk, который содержит локальный адрес и порт. Мы используем cutдля разделения адреса и порта с :разделителем и оставляем только последний ( -f2). ssтакже выведите заголовок, от которого мы избавляемся, grepпропингуя непустые последовательности чисел, длина которых не превышает 5. Затем мы commвыполняем требования, используя sortчисленно ( -n) и избавляясь от дубликатов с помощью uniq.

Теперь у нас есть отсортированный список открытых портов, что мы можем shufFLE , чтобы затем захватить первые "$HOWMANY"те , с head -n.

пример

Захватите три случайных открытых порта в частном диапазоне (49152-65535)

comm -23 <(seq 49152 65535) <(ss -tan | awk '{print $4}' | cut -d':' -f2 | grep "[0-9]\{1,5\}" | sort | uniq) | shuf | head -n 3

может вернуться к примеру

54930
57937
51399

Примечания

  • переключаться -tс -uв , ssчтобы получить свободные порты UDP вместо этого.
  • бросьте, shufесли вы не заинтересованы в захвате случайного порта

1
Мне нравится ваш однострочный текст, эта версия правильно анализирует IPv6, например [:: ​​1]: 52792 и использует параметр --no-header вместо grep. gist.github.com/fstefanov/ff4dcec7ded59514421bf944d1bb9a6f
Филипп Стефанов

1

Мне нужно было найти только один случайный неиспользуемый порт и не печатать их список. Вот мое решение Bash.

#/bin/bash

function random_unused_port {
    local port=$(shuf -i 2000-65000 -n 1)
    netstat -lat | grep $port > /dev/null
    if [[ $? == 1 ]] ; then
        export RANDOM_PORT=$port
    else
        random_unused_port
    fi
}

random_unused_port

И использовать его, поставив его

$ . ./random_unused_port.sh; echo $RANDOM_PORT

Мне нравится идея здесь, однако ваша команда grep не вернет то, что вы намеревались. Хорошо, что он будет консервативным, но если следующий случайный порт - 2000, а порт 2000 открыт, но порт 20000 используется, он продолжит искать, поэтому в результате будет получен не полный диапазон доступных портов.
Ник

1

Возможно другое решение, основанное на списке используемых портов:

function random_unused_port {
   (netstat --listening --all --tcp --numeric | 
    sed '1,2d; s/[^[:space:]]*[[:space:]]*[^[:space:]]*[[:space:]]*[^[:space:]]*[[:space:]]*[^[:space:]]*:\([0-9]*\)[[:space:]]*.*/\1/g' |
    sort -n | uniq; seq 1 1000; seq 1 65535
    ) | sort -n | uniq -u | shuf -n 1
}

RANDOM_PORT=$(random_unused_port)

Команда netstatгенерирует список всех открытых портов. Команда sedизвлекает номера портов, которые используются, а конструкция sort/ uniqвозвращает уникальный список открытых портов. Второй шаг - создать список номеров портов, начиная с 1 и заканчивая 1000 (зарезервированные порты), и дополнительный список всех номеров портов, начиная с 1 до 65535. Финальный список содержит все доступные порты только один раз и uniq -uбудет извлекать их , И, наконец, shuf -n 1будет выбран один случайный порт из полного списка доступных портов. Тем не менее, будет состояние гонки, прежде чем можно будет зарезервировать порт.


1

Мне нужно было найти следующий открытый порт, начиная с номера порта; Вот моя попытка использовать решение @Taras.

_check="placeholder"
START_FROM=1900
PORT=$(( ( "$RANDOM" % 1000 ) + $START_FROM ))
while [[ ! -z "${_check}" ]]; do
    ((PORT++))
    _check=$(ss -tulpn | grep ":${PORT}")
done

0

Если ваш порт 54321, запустите:

sudo netstat -ap |grep 54321

Некоторые варианты использования netstat можно найти здесь .


Эта команда покажет мне только если порт 54321 используется или нет. То, что я хочу, это найти неиспользуемый порт.
user2429082

Неиспользованное - неоднозначно. Вы хотите проверить, какой порт доступен для прослушивания? Или к какому порту можно подключиться? Любые, которые не используются, доступны. Как пользователь, вы можете использовать те, которые выше 1024, в качестве root, вы можете использовать также те, которые ниже 1024.
Overmind
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.