Команда Linux отримує невикористаний порт


20

Я шукаю команду або скрипт, який повертає невикористаний порт в моїй системі Linux ubuntu. Я шукаю в Інтернеті, і єдине, що я знаходжу, - це про порт / Слухати порт із командою nestat. Мабуть, щось із командою netstat буде працювати, але не знаю, що саме. Будь-яка ідея як?

Спасибі.



1
Чому саме це потрібно робити? Якщо ви розробляєте сервер, ви можете прив’язати до порту 0, і ОС виділить для вас безкоштовний порт, вам нічого не потрібно шукати. В іншому випадку пошук, а потім зв'язування схильний до умов перегонів. Дивіться, наприклад , stackoverflow.com/questions/1365265 / ... або stackoverflow.com/questions/1075399 / ...
Патрік Mevzek

Відповіді:


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?
Ніл Стівенс

export PORT = $ (ruby -e 'вимагають "socket"; ставить Addrinfo.tcp ("", 0) .bind {| s | s.local_address.ip_port}')
G. Sylvie Davies

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
Nick

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також виводимо заголовок, від якого ми позбавляємося за допомогою grepping за не порожні послідовності чисел, що не перевищують 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

Мені потрібно було знайти лише один випадковий невикористаний порт і не надрукувати їх список. Ось мій баш-рішення.

#/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 використовується чи ні. Я хочу знайти невикористаний порт.
користувач2429082

Невикористаний неоднозначно. Ви хочете перевірити, який порт доступний для прослуховування? Або з яким портом можна підключитися? Будь-які, які не використовуються, доступні. Як користувач, ви можете використовувати ті , вище 1024, як корінь, ви можете також використовувати ті під 1024.
Сверхразум
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.