Bash script telnet to test multiple addresses and ports

27,210

As other stackoverflower's said, I would recommend using nmap or netcat if avilable. However, if you cannot use those software, you can use bash's builtin /dev/tcp/<host>/<port> instead.

http://www.gnu.org/software/bash/manual/bashref.html#Redirections

I could'nt figure out which version of bash you are using, but /dev/tcp/... seems to implemented since some old bash.

#!/bin/bash
echo "scanme.nmap.org 21
scanme.nmap.org 22
scanme.nmap.org 23
scanme.nmap.org 79
scanme.nmap.org 80
scanme.nmap.org 81" | \
while read host port; do
  r=$(bash -c 'exec 3<> /dev/tcp/'$host'/'$port';echo $?' 2>/dev/null)
  if [ "$r" = "0" ]; then
    echo $host $port is open
  else
    echo $host $port is closed
  fi
done

This produces

scanme.nmap.org 21 is closed
scanme.nmap.org 22 is open
scanme.nmap.org 23 is closed
scanme.nmap.org 79 is closed
scanme.nmap.org 80 is open
scanme.nmap.org 81 is closed

UPDATED: The following can do timeout. Although it may seem little tricky, idea is just to kill the child process after some timeout.

Bash script that kills a child process after a given timeout

#!/bin/bash
echo "scanme.nmap.org 80
scanme.nmap.org 81
192.168.0.100 1" | (
  TCP_TIMEOUT=3
  while read host port; do
    (CURPID=$BASHPID;
    (sleep $TCP_TIMEOUT;kill $CURPID) &
    exec 3<> /dev/tcp/$host/$port
    ) 2>/dev/null
    case $? in
    0)
      echo $host $port is open;;
    1)
      echo $host $port is closed;;
    143) # killed by SIGTERM
       echo $host $port timeouted;;
     esac
  done
  ) 2>/dev/null # avoid bash message "Terminated ..."

this produces

scanme.nmap.org 80 is open
scanme.nmap.org 81 is closed
192.168.0.100 1 timeouted

since 192.168.100 does not exist in my local network.

Share:
27,210
Kyle
Author by

Kyle

Updated on February 07, 2020

Comments

  • Kyle
    Kyle about 4 years

    I am required to test at least 130 ip addresses and ports. I am hoping to write a bash script such that it reads the ip address and ports from an input file.

    I have the following

    while read line
    do
    telnet $line >> $2
    done < $1
    

    This is a crappy code as it cannot determine whether its connected or failed, and I have to rely on its auto escape character to disconnect from a connection.

    How can I improvise this such that it updates $2 with the status quickly? I am working on Redhat and do not have netcat or expect installed..

  • Kyle
    Kyle almost 10 years
    Is there a way to also echo those hosts that are unreachable? This is great, but would need to also somehow determine if the server can communicate with the target host I have several hosts that timeouts
  • ymonad
    ymonad almost 10 years
    I added timeout option.
  • Adrian Frühwirth
    Adrian Frühwirth almost 10 years
    It was implemented in bash-2.04-devel (ChangeLog) so if you know that you run bash and not some other shell it's old enough that you can pretty much rely on having the feature.