Bash script telnet to test multiple addresses and

2019-04-02 04:55发布

问题:

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..

回答1:

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.