AJF
AJF

Reputation: 1931

How to find a free TCP port

How do I find a completely free TCP port on a server? I have tried the command line;

netstat -an

but I am told the ones with a status of LISTENING are already being used.

I also tried a tool called TCPView but again it only showed which TCP ports were being used. I know how to telnet to a port to check its open but I need to find one that is free.

Upvotes: 15

Views: 39384

Answers (5)

Mandy Schoep
Mandy Schoep

Reputation: 981

With just using pure Bash, you can do the following to get all available TCP ports between 1024 and 1030:

$ for i in {1024..1030}; do echo -n 2>/dev/null < "/dev/tcp/localhost/$i" && echo -n || echo "$i"; done
1024
1025
1026
1027
1028
1029
1030

When the echo < "/dev/tcp/localhost/$i" returns a non 0 status code, it will echo the port number.

Sometimes you just want the first available port, which you can do with the following, by breaking out of the loop early:

$ for i in {1024..1030}; do echo -n 2>/dev/null < "/dev/tcp/localhost/$i" && echo -n || { echo "$i"; break; }; done
1024

Upvotes: 0

Tom Saleeba
Tom Saleeba

Reputation: 4217

Building on the answer by @Fengzmg:

This implementation:

  • uses the newer ss instead of netstat
  • doesn't rely on grep-ing the output, instead we use the filter interface in ss
  • is more robust because:
    • we only match the source port (sport), instead of the grep approach that would match destination ports
    • better support for ports that have fewer than 5 digits as we won't match substrings. The grep approach would match 443 in 30443.

Note: the -4 restricts to only IPv4. There's also -6 but you can not specify either to match on both.

BASE_PORT=1234
INCREMENT=1

port=$BASE_PORT

while [ -n "$(ss -tan4H "sport = $port")" ]; do
  port=$((port+INCREMENT))
done

echo "Usable Port: $port"

Upvotes: 2

Fengzmg
Fengzmg

Reputation: 768

Inspired by https://gist.github.com/lusentis/8453523

Start with a seed port, and increment it till it is usable

BASE_PORT=16998
INCREMENT=1

port=$BASE_PORT
isfree=$(netstat -taln | grep $port)

while [[ -n "$isfree" ]]; do
    port=$[port+INCREMENT]
    isfree=$(netstat -taln | grep $port)
done

echo "Usable Port: $port"

Upvotes: 8

kenorb
kenorb

Reputation: 166871

In Bash you can write simple for loop to check which TCP ports are free, e.g.

$ for i in {1..1024}; do (exec 2>&-; echo > /dev/tcp/localhost/$i && echo $i is open); done
22 is open
25 is open
111 is open
587 is open
631 is open
841 is open
847 is open
1017 is open
1021 is open

For more info, check: Advanced Bash-Scripting Guide: Chapter 29. /dev and /proc

Upvotes: 3

NeverGiveUp161
NeverGiveUp161

Reputation: 870

netstat -lntu

This will solve your purpose.

Upvotes: 9

Related Questions