Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

How can I quickly find out whether port 80 is open/listening on a server via a bash script?

Normally on all workstations the daemon is running, but sometimes it fails. I use the following command to check if an IP address has an open port. I would like to be able to do this for every line in a file without having to manually type it each time.

 nc -zw3 10.101.0.13 80 && echo "opened" || echo "closed"

The list file looks like this, where 3333 and 3334 are strings after $ip;

10.101.0.13; 3333
10.101.0.15; 3334
10.101.0.17; 4143
10.101.0.21; 1445
10.101.0.27; 2443
10.101.0.31; 2445
10.101.0.47; 3443
10.101.0.61; 3445

I have to separate open ports from closed ones, so I'll have a list of failed servers that will have to be fixed.

I tried something like this without success:

while IFS=";" read ip port ; do nc -zw3 "$ip" "$port" && echo "$ip:$port => opened" || echo "$ip:$port =>  closed" ; done < list.txt

while IFS=";" read ip port ; do nc -zw3 "${ip}" "${port}" && echo "${ip}:${port} => opened" || echo "${ip}:${port} =>  closed" ; done < list.txt
share|improve this question
    
The wait flag isn't available/won't work as you intend here for every version of nc, can you try running one of your nc -zw3 in shell with one open and one closed port and see if it really returns after 3 seconds? –  BroSlow Jan 29 at 9:41
    
yes, with opened one i get response within 10 miliseconds Connection to localhost 80 port [tcp/http] succeeded! and with bad one, within the same 10 miliseconds i get empty line. –  Mikhael Djekson Jan 29 at 15:52
    
What you describe works perfectly for me. Why do you say it's not working? –  terdon Jan 29 at 16:26
add comment

3 Answers

up vote 1 down vote accepted

Here's the most basic and efficient Nmap command to do what you want (and nothing more):

#!/bin/sh
# Gather the IPs to scan for each port
perl -lanF\; -e'push @{$p{$F[1]}}, $F[0];END{$,=" ";while(($x,$y)=each%p){print $x,@$y}}' input.txt | while read port ips; do
  # Scan the appropriate port for each set of IPs
  nmap -Pn -n -oG - -p $port $ips |\
  # Put the open ones into open.txt and the closed/filtered into closed.txt
  awk 'OFS=":";$4~/^Ports:/{if(/open/){print $2,'$port' >> "open.txt"}else{print $2,'$port' >> "closed.txt"}}'
done

Unfortunately, Nmap does not have a built-in way to scan only some ports on some IPs and other ports on other IPs, otherwise this could be a lot simpler.

share|improve this answer
add comment
#!/bin/bash
N=0
cat $1 | while read line
do
    N=$((N+1))
    nc -zw3 $( echo $line | tr -d ';' ) && echo -e "OPEN\t$( echo $line | sed 's/; /:/g' )" || echo -e "CLOSED\t$( echo $line | sed 's/; /:/g' )" 
done

Usage: ./script.sh Scans the file specified and tests if each "$ip; $port" is open or closed.

If you want sorted output: ./script.sh | sort

No installation necessary.

As one line that you can paste into your terminal without having to make a shell script:

N=0; cat FILENAME | while read line; do; N=$((N+1)); nc -zw3 $( echo $line | tr -d ';' ) && echo -e "OPEN\t$( echo $line | sed 's/; /:/g' )" || echo -e "CLOSED\t$( echo $line | sed 's/; /:/g' )"; done
share|improve this answer
add comment

Easiest thing is to install nmap from the repos, then do:

   awk -F ";" '{print $1}' data | xargs -L 1 nmap -p 80

where data is the file with the IP addresses to scan.

Edit:

If it is true,as @pabouk suggests below, that the number following the IP address is port to be scanned, then you can achieve the desired scan as follows:

   awk -F ";" '{print "nmap " $1 " -p" $2}' data | xargs -I % sh -c '%'

If you wish scan for both port 80, and the port read from the file, you can do it with this command:

   awk -F ";" '{print "nmap " $1 " -p80," $2}' data | xargs -I % sh -c '%'

If nmap is thought to produce too much output, the follwoing command will do:

   awk -F ";" '{print "nmap -oG - " $1 " -p80," $2}' data | xargs -I % sh -c '%' | grep Ports
share|improve this answer
    
You are ignoring the port numbers from the data file. –  pabouk Feb 1 at 18:42
    
I understand it that each line of the file contains this pair to scan: IP_address; port. Also nmap produces a lot of (in this case superfluous) output with every run. –  pabouk Feb 1 at 18:48
    
It still produces a lot of junk output. You could append: "| grep tcp | sort" (no quotes) to get rid of (most of) the junk and even sort the output according to port. –  dma1324 Feb 1 at 19:25
    
Yes, nmap -oG - ... | grep Ports: is what I tested just a moment ago. :) –  pabouk Feb 1 at 19:35
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.