Какой самый простой способ найти неиспользуемый локальный порт?
В настоящее время я использую что-то похожее на это:
port=$RANDOM
quit=0
while [ "$quit" -ne 1 ]; do
netstat -a | grep $port >> /dev/null
if [ $? -gt 0 ]; then
quit=1
else
port=`expr $port + 1`
fi
done
Это кажется ужасно окольным, поэтому мне интересно, есть ли более простой путь, такой как встроенный, который я пропустил.
shell
networking
shell-script
netstat
mybuddymichael
источник
источник
-n
к netstat и более избирательному grep). Чтобы сделать это, попробуйте открыть порт в любом нужном вам режиме и попробуйте другой, если он недоступен.ssh -D
в качестве сервера SOCKS.Ответы:
Если ваше приложение поддерживает это, вы можете попробовать передать порт 0 приложению. Если ваше приложение передает это ядру, порт будет динамически выделяться во время запроса и гарантированно не будет использоваться (выделение не будет выполнено, если все порты уже используются).
В противном случае вы можете сделать это вручную. У сценария в вашем ответе есть условие гонки, единственный способ избежать этого - атомарно проверить, открыт ли он, пытаясь его открыть. Если порт используется, программа должна завершиться с ошибкой, чтобы открыть порт.
Например, скажем, вы пытаетесь слушать с GNU netcat.
источник
$port
в реальной программе, как вwhile ...; done; program --port $port
.Мое решение состоит в том, чтобы привязать к порту 0, который просит ядро выделить порт из его ip_local_port_range. Затем закройте сокет и используйте этот номер порта в вашей конфигурации.
Это работает, потому что ядро, похоже, не использует номера портов до тех пор, пока это не будет необходимо. Последующие привязки к порту 0 будут назначать другой номер порта. Код Python:
Это дает только номер порта, например.
60123
,Запустите эту программу 10 000 раз (вы должны запустить их одновременно), и вы получите 10 000 различных номеров портов. Поэтому я думаю, что использовать порты довольно безопасно.
источник
python -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()'
{ 1: 7006, 2: 1249, 3: 151, 4: 8, 5: 1, 6: 1}
ruby -e 'puts Addrinfo.tcp("", 0).bind { |s| s.local_address.ip_port }'
Один лайнер
Я собрал хороший однострочный текст, который быстро служит цели, позволяя захватывать произвольное количество портов в произвольном диапазоне (здесь он разделен на 4 строки для удобства чтения):
Построчно
comm
утилита, которая сравнивает строки в двух файлах, которые должны быть отсортированы по алфавиту. Он выводит три столбца: строки, которые появляются только в первом файле, строки, которые появляются только во втором файле, и общие строки. Указывая,-23
мы подавляем последние столбцы и оставляем только первый. Мы можем использовать это, чтобы получить разницу двух наборов, выраженную в виде последовательности текстовых строк. Я узнал об этомcomm
здесь .Первый файл - это диапазон портов, из которых мы можем выбирать.
seq
производит отсортированную последовательность чисел от$FROM
до$TO
. Результат сортируется по алфавиту (а не по номерам) и передается вcomm
качестве первого файла с использованием процесса подстановки .Второй файл - это отсортированный список портов, который мы получаем, вызывая
ss
команду (имея в-t
виду TCP-порты, то-a
есть все установленные и прослушиваемые - и-n
числовые - не пытайтесь разрешить, скажем,22
кssh
). Затем мы выбираем только четвертый столбец сawk
, который содержит локальный адрес и порт. Мы используемcut
для разделения адреса и порта с:
разделителем и оставляем только последний (-f2
).ss
также выведите заголовок, от которого мы избавляемся,grep
выполняя команду ping для непустых последовательностей чисел, которые не длиннее 5. Затем мыcomm
выполняем требования, используяsort
без дубликатов-u
.Теперь у нас есть отсортированный список открытых портов, что мы можем
shuf
FLE , чтобы затем захватить первые"$HOWMANY"
те , сhead -n
.пример
Захватите три случайных открытых порта в частном диапазоне (49152-65535)
может вернуться к примеру
Примечания
-t
с-u
в ,ss
чтобы получить свободные порты UDP вместо этого.shuf
на,sort -n
если вы предпочитаете, чтобы доступные порты сортировались по номерам вместо случайныхисточник
Кредиты Крису Дауну
источник
Очевидно, что TCP-соединения могут использоваться в качестве файловых дескрипторов в linux из bash / zsh. Следующая функция использует эту технику и должна быть быстрее, чем вызов netcat / telnet.
Инструкции по использованию: связать вывод с переменной и использовать в сценариях. Проверено на Ubuntu 16.04
источник
ksh93
также.$[$LPORT + ($RANDOM % ($UPORT-$LPORT))]
.\n
на любой порт прослушивания, хотя :) Я бы предложил добавить-n
. При этом все равно будет пытаться открыть соединение, но ничего не будет отправлено, но будет немедленно отключено.Вот кроссплатформенный, эффективный «oneliner», который забирает все используемые порты и дает вам первый доступный от 3000 и более:
Вы можете просто объединить все строки, чтобы они были в одной строке. Если вы хотите получить первый доступный номер с другого номера порта, измените назначение на
i
вfor
цикле.Он работает как на Mac, так и на Linux, поэтому необходимо
[:.]
регулярное выражение.источник
-a
и не-t
просто посмотреть на сокеты TCP (6)?ss -Htnl
может быть лучше (и быстрее! - не то, чтобы я заботился об этом: P).-t
, по крайней мере, тот, который поставляется с Apple, иss
также отсутствует в macOS.netstat -aln
даже работает на солярисе.В Linux вы можете сделать что-то вроде:
Чтобы найти первый свободный порт выше 1080. Обратите внимание, что он
ssh -D
будет привязан к интерфейсу обратной связи, поэтому теоретически вы можете повторно использовать порт 1080, если сокет связал его с другим адресом. Другим способом было бы попытаться связать это:источник
ssh -D
, я не вижу лучшего варианта.-O forward
Вариантssh
не возвращает ошибку , когда вперед неудачи.Это версия, которую я использую:
Команда
shuf -n 1 -i 49152-65535
дает вам «случайный» порт в динамическом диапазоне. Если он уже используется, пробуется другой порт в этом диапазоне.Команда
netstat -atun
перечисляет все порты (-a) TCP (-t) и UDP (-u), не тратя время на определение имен хостов (-n).источник
Это часть функции, которая есть в моем .bashrc, которая динамически создает SSH-туннели и пытается использовать любой порт в диапазоне:
YMMV
источник
Еще один бег на этой старой лошади-хобби:
Этот код делает чисто переносное использование
netstat
,egrep
,awk
, и др. Обратите внимание, что для внешних команд выдается только вызов, чтобы получить список занятых портов в начале. Можно запросить один или несколько свободных портов:и начать с произвольного порта:
источник
Моя комбинация из других ответов выше. Возьми:
С помощью shuf -n1 мы берем одно случайное число из диапазона (-i) в / proc / sys / net / ipv4 / ip_local_port_range. shuf нужен синтаксис с тире, поэтому мы используем tr для изменения табуляции в тире.
Далее мы используем netstat, чтобы показать нам все (-a) соединения tcp и udp (-u -t) в числах (-n), если мы найдем наш случайный порт $ port в этом (начинаем с: и заканчиваем w пробелами ( \ s) тогда нам нужен другой порт и так далее. В противном случае (grep -q имеет код возврата> 0, мы оставили цикл while и $ port установлен.
источник
Если у вас есть Python, я бы сделал это:
источник
Я написал этот маленький скрипт на Python2 / 3, который может помочь вам в следующий раз:
https://github.com/sdenel/find-unused-local-port
источник
Мой взгляд на это ... функция пытается найти
n
последовательные свободные порты:источник