28

Is there any command I can run from bash that will tell me whether a port is already open?

10 Answers 10

39

Use "netstat" to check the presently using ports.

netstat -antp

Proto Recv-Q Send-Q Local Address        Foreign Address   State    PID/Program name
tcp        0      0 xxx.xxx.xxx.xxx      0.0.0.0:*         LISTEN   16297/named     
tcp        0      0 xxx.xxx.xxx.xxx:53   0.0.0.0:*         LISTEN   16297/named     
tcp        0      0 xxx.xxx.xxx.xxx:53   0.0.0.0:*         LISTEN   16297/named     
tcp        0      0 127.0.0.1:53         0.0.0.0:*         LISTEN   16297/named     
1
  • 3
    "netstat -antp | grep 80" where 80 is port number to search for.
    – Umair A.
    May 17, 2013 at 9:30
13

This (netstat) is the fastest solution...

netstat -lnt

...but this gives you more control (at the cost of speed (sometimes a lot of speed))...

lsof -n -i -a -u www-data

The above example for example shows you all the TCP ports open and in the LISTEN state, AND (-a) belonging to the Apache (www-data) user.

0
8

All good answers.

However you don't mention if you are logged onto the computer in question. ;P

If not, then nmap is your friend.

for starters try:

nmap -Otarget

amap is also a good choice which will also attempt to guess server software by grabbing banner pages.

for starters try:

amaptarget1-6000

7

Try

lsof -i :<port number>

If you get any results, something is listening and bound, eg

# lsof -i :80
COMMAND   PID   USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
nginx    1833 nobody    3u  IPv4 51091229      0t0  TCP odessa.cheney.net:http->79.173.188.214:52918 (ESTABLISHED)
nginx    1833 nobody    5u  IPv4 46221856      0t0  TCP odessa.cheney.net:http->66.36.243.182:37876 (CLOSE_WAIT)
nginx    1833 nobody    9u  IPv4 34733048      0t0  TCP localhost.localdomain:http (LISTEN)
nginx    1833 nobody   10u  IPv4 34733049      0t0  TCP odessa.cheney.net:http (LISTEN)
nginx    1833 nobody   14u  IPv4 46221857      0t0  TCP odessa.cheney.net:http->66.36.243.182:37880 (CLOSE_WAIT)
nginx    1833 nobody   15u  IPv4 51091030      0t0  TCP odessa.cheney.net:http->msnbot-65-55-106-132.search.msn.com:51708 (ESTABLISHED)
nginx   11832   root    9u  IPv4 34733048      0t0  TCP localhost.localdomain:http (LISTEN)
nginx   11832   root   10u  IPv4 34733049      0t0  TCP odessa.cheney.net:http (LISTEN)
4
netstat -tlnp  

Show tcp ports that are listening, show numbers only (don't resolve names - makes it was faster) and show the process that is doing the listening (the p only works if you are root)

netstat -ulnp  

Show udp ports that are listening, show numbers only (don't resolve names - makes it was faster) and show the process that is doing the listening (the p only works if you are root)

netstat -unp  

Show udp ports that are open but not listening, show numbers only (don't resolve names- makes it was faster) and show the process that is doing the listening (the p only works if you are root)

netstat -an

Show all ports in use, show numbers only - don't resolve names

lsof -i <proto>@<host>:<port>

e.g

lsof -i tcp@localhost:25

to see if anything is listening on port localhost 25/TCP, or

lsof -i [email protected]:636 

to see if there are any sockets either local or remote either listening (local) or connected to (local or remote) for any host/interface

2

lsof (list open files) is a good tool to see if a process is listening on a port

lsof -P | grep :<port-number>

netstat is a good tool for seeing if there are any active connections.

netstat -n | grep :<port-number>

2

You don't mention what protocol you want to use, i.e. TCP or UDP - and it's also important to realise that "port" isn't quite as granular the system supports to disambiguate sockets. E.g. if your system has multiple IP addresses then port 80 might be in use on all IP addresses (either the application has bound to "0.0.0.0" or "::" or to each IP address in succession), or it might be in use only on a subset of those IP addresses.

The best, and surest, way to determine if a port/address is free and available is to attempt to bind to it. Netcat is handy for this.

nc -l [-s a.b.c.d] -p NN

will attempt to bind to TCP port NN on (optional, the default will be all addresses) a.b.c.d. Add the -u option to do the same in UDP.

Next, to tell if the port is truly "open" as you ask - you need to start looking at potential firewall rules. Again the easiest thing is to try to connect to the port. Use netcat as above, on the server, and from a client use netcat to attempt to the connect to the port you opened.

nc [-u] a.b.c.d NN

will connect to port NN on a.b.c.d, using UDP if the -u flag is specified. You can then type input into the client end, and it should show up on the server. If it doesn't, you need to look into system and network specific tools.

1
  • This looks nice, except that nc -l keeps listening until it connects to a client. Is there a way to return success immediately?
    – Quantum7
    Sep 24, 2020 at 13:55
2

I use fuser (in package psmisc):

fuser -n tcp PORT

Brings back the pid of process bound to this port.

If this is to know if a port is listening, the good old telnet does the trick :)

telnet 127.0.0.1 PORT

2

This one-liner will get you a list of all TCP ports in use. It works in bash on Ubuntu and OS X.

netstat -ant | sed -e '/^tcp/ !d' -e 's/^[^ ]* *[^ ]* *[^ ]* *.*[\.:]\([0-9]*\) .*$/\1/' | sort -g | uniq

The list will have one port per line without any extra information.

1
  • Love it! gret drop in for bash scripts, e.g.: for port in $(netstat -ant | sed -e '/^tcp/ !d' -e 's/^[^ ]* *[^ ]* *[^ ]* *.*[\.:]\([0-9]*\) .*$/\1/' | sort -g | uniq); do echo EXECUTE COMMAND FOR PORT $port; done Oct 29, 2015 at 18:30
0

A lot ways of doing it gave me issues because they didn't work on linux and osx, and/or because they didn't show the ports used by docker, or processes that were owned by root. Now I just use this javascript program:

(make sure you have node installed and that it works with node not just nodejs or change the program accordingly)

save the following to a file called check-port in your path or in your project

#!/usr/bin/env node
var http = require('http');
var app = new http.Server();
app.listen(process.argv[2], () => {
  process.exit(0)
});

set permissions

chmod +x path/to/check-port

run from your path

check-port 8080

or run from the same directory

./check-port 8080

so far it is working pretty well.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .