Finding next open port - bash

Is there any way, using basic Unix commands, to find the next unused port number, starting at port 4444 and going upwards? I'm ssh'ed (via openssh) into a Windows XP machine, running Cygwin tools and using a bash shell.
Thanks, - Dave

Try this:
for port in $(seq 4444 65000); do echo -ne "\035" | telnet 127.0.0.1 $port > /dev/null 2>&1; [ $? -eq 1 ] && echo "unused $port" && break; done
where
seq 4444 65000 - port range for check
echo -ne "\035" - escape character to force close telnet session (^])
if telnet finishes with exit code 1 that mean connection refused:
$ telnet 127.0.0.1 4444
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
telnet: Unable to connect to remote host
$ echo $?
1
else we decided that connection was success with exit code 0.
EDIT:
Special for cygwin: You need to install additional package inetutils that is contain telnet port and use the script as follows:
for port in $(seq 4444 65000); do echo -ne "\035" | /usr/bin/telnet 127.0.0.1 $port > /dev/null 2>&1; [ $? -eq 1 ] && echo "unused $port" && break; done

Same as above, but written as a function
function get_unused_port() {
for port in $(seq 4444 65000);
do
echo -ne "\035" | telnet 127.0.0.1 $port > /dev/null 2>&1;
[ $? -eq 1 ] && echo "$port" && break;
done
}
FREE_PORT="$(get_unused_port)"
echo $FREE_PORT

The following function doesn't depend on telnet/netcat as it generates a random port in the local port range and compares it with a list of ports currently used by running applications.
Should work on any *nix that supports proc filesystem. Generates a free ephemeral port to be used by your application.
function EPHEMERAL_PORT(){
while true; do
LISTENING_PORTS=$(cat /proc/net/tcp | awk 'NR >1 {print $2}' | awk -F':' '{print $2}');
LISTENING_PORTS=$(for PORT in ${LISTENING_PORTS}; do echo $((16#${PORT})); done|sort -g);
# echo "32768 60999" | read LPORT UPORT
read LPORT UPORT < /proc/sys/net/ipv4/ip_local_port_range
MPORT=$[$LPORT + ($RANDOM % $UPORT)];
if (echo "${LISTENING_PORTS[#]}" | grep -xqv $MPORT); then
echo $MPORT;
break;
fi
done
}
Apparently TCP connections can be used as file descriptors on linux. The following function uses that technique and should be faster than the previous one.
function EPHYMERAL_PORT(){
LPORT=32768;
UPORT=60999;
while true; do
MPORT=$[$LPORT + ($RANDOM % $UPORT)];
(echo "" >/dev/tcp/127.0.0.1/${MPORT}) >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo $MPORT;
return 0;
fi
done
}
This is a cross platform function that uses osquery to get a list of listening ports. Should also work on Windows.
function EPHYMERAL_PORT(){
while true; do
echo "32768 60999" | read LPORT UPORT
MPORT=$[$LPORT + ($RANDOM % $UPORT)];
LISTENING_PORTS=$(osqueryi --header=false --list "select port from listening_ports order by port");
if (echo "${LISTENING_PORTS[#]}" | grep -xqv $MPORT); then
echo $MPORT;
break;
fi
done
}
Usage instructions. Bind the output to a variable and use in scripts. Tested on Ubuntu 16.04
root#ubuntu:~> EPHYMERAL_PORT
59453
root#ubuntu:~> PORT=$(EPHYMERAL_PORT)

Related

bash - using a command line argument (hostname) to run an external command

First time post, please forgive any missing information.
I have a script that is supposed to work with icinga. I need icinga to log into my Linux box and run a command like "script ". The script will then run a command to that hostname like sudo /etc/init.d/apache2 status then report back "running or unused" and an exit status of 0 or 2.
I'm wondering how I could add another command and have it one or the other run depending on what hostname it's given. Half of them need apache2 to be running and the other half need to have a process called dss to be running. I'd rather not have two separate scripts. Here is the working script and sorry it's sloppy but I haven't done any clean up and I'm not real good at bash yet.
so the user would run the script ./chkdss2 or
#!/bin/bash
ec=0
ec1=2
var3=run
var4=unused
for host in "$#"
do
var1=`ssh $host sudo /etc/init.d/dss status|awk '{print $6}'`
var2="$( echo $var1 | cut -c 3-5 )"
if [[ "$var2" == "$var3" ]]; then
echo "$host is running"
echo $ec
else
echo "$host is not running"
echo $ec1
fi
done
There are a couple ways to test if a particular hostname is for apache or dss. You only need to have a list of hostnames for each case, and check if the received hostnames are included in said lists.
Method 1: using arrays
#!/bin/bash
# Method 1, using array lists of hosts
apachehosts=('ap1' 'ap2' 'ap3')
dsshosts=('dss1' 'dss2' 'dss3')
for host in "$#"
do
if printf '%s\n' "${apachehosts[#]}" | grep -Fxq "$host"
then
echo "$host: APACHE HOST"
elif printf '%s\n' "${dsshosts[#]}" | grep -Fxq "$host"
then
echo "$host: DSS HOST"
else
echo "ERROR, $host: unknown host"
fi
done
To modify the lists of hosts, simply add or remove values in the declaration of arrays apachehosts and dsshosts.
Method 2: using case
#!/bin/bash
# Method 2, using case
for host in "$#"
do
case "$host" in
'ap1'|'ap2'|'ap3')
echo "CASE, $host: APACHE HOST"
;;
'dss1'|'dss2'|'dss3')
echo "CASE, $host: DSS HOST"
;;
*)
echo "ERROR CASE, $host: unknown host"
;;
esac
done
Here, you edit the patterns in each case.
Method 3: using if
#!/bin/bash
# Method 3, using if
for host in "$#"
do
if [[ "$host" == 'ap1' || "$host" == 'ap2' || "$host" == 'ap3' ]]
then
echo "IF, $host: APACHE HOST"
elif [[ "$host" == 'dss1' || "$host" == 'dss2' || "$host" == 'dss3' ]]
then
echo "IF, $host: DSS HOST"
else
echo "IF, $host: unknown host"
fi
done
Here you modify the if conditions. I prefer the other methods, since this one is more complicated to edit, it is not as clear, especially if your list of hosts is long.
Method 4: condition on the hostnames
If you are lucky, there is some pattern to your hostnames. Ex. all apache servers start with letters ap, all your dss servers include dss in the name, ...
You can then simply use 2 if statements to decide which is which.
#!/bin/bash
# Method 4, patterns
for host in "$#"
do
if [[ $(echo "$host" | grep -c -e "^ap") -ne 0 ]]
then
echo "PATTERNS, $host: APACHE HOST"
elif [[ $(echo "$host" | grep -c -e "dss") -ne 0 ]]
then
echo "PATTERNS, $host: DSS host"
else
echo "PATTERNS, $host: unknown host"
fi
done
Note: hostname apdss1 would come out as an Apache server here. Previous methods would respond "unknown host". You patterns must be strict enough to avoid mismatches.
I had a similar task to get few report items using single ssh request.
I had to retrieve in singel ssh command:
Full hostname (FQDN)
Linux version
IP address of its Docker host if exist, or "none"
I got my script to work in 3 stage.
1. Get multiple lines of information from remote host
ssh -q dudi-HP-Compaq-Elite-8300-MT <<< '
date +%F:%T # line 1: time stamp
hostname -f # line 2: hostname
awk "/DESCR/{print \$3}" /etc/lsb-release # line 3 : host linux distribution version
ip a | awk "/inet / && !/127.0.0.1/{sub(\"/.*\",\"\",\$2);printf(\"%s \", \$2)}" # line 4: list IP address to the host
'
Results:
2022-03-05:22:22:21
dudi-HP-Compaq-Elite-8300-MT
20
192.168.2.111 192.168.122.1 172.17.0.1
2. Process multiple lines of information from remote host
Read lines of information from remote host, into an array sshResultsArr.
readarray -t sshResultsArr < <(ssh -q dudi-HP-Compaq-Elite-8300-MT <<< '
date +%F:%T # line 1: time stamp
hostname -f # line 2: hostname
awk "/DESCR/{print \$3}" /etc/lsb-release # line 3 : host linux distribution version
ip a | awk "/inet / && !/127.0.0.1/{sub(\"/.*\",\"\",\$2);printf(\"%s \", \$2)}" # line 4: list IP address to the host
')
hostname=${sshResultsArr[1]}
osVersion=${sshResultsArr[2]}
hasDockerIp=$(grep -Eo "172(.[[:digit:]]{1,3}){3}" <<< "${sshResultsArr[3]}") # find IP starting with 172
hasDockerIp=${hasDockerIp:="none"} # if not found IP set to "NONE"
printf "%s \t OS version: %s \t has Docker IP: %s\n" "$hostname" "$osVersion" "$hasDockerIp"
Result:
dudi-HP-Compaq-Elite-8300-MT OS version: 20 has Docker IP: 172.17.0.1
3. Process each remote host in a loop
#!/bin/bash
for host in "$#"; do
readarray -t sshResultsArr < <(ssh -q $host <<< '
date +%F:%T # line 1: time stamp
hostname -f # line 2: hostname
awk "/DESCR/{print \$3}" /etc/lsb-release # line 3 : host linux distribution version
ip a | awk "/inet / && !/127.0.0.1/{sub(\"/.*\",\"\",\$2);printf(\"%s \", \$2)}" # line 4: list IP address to the host
')
hostname=${sshResultsArr[1]}
osVersion=${sshResultsArr[2]}
hasDockerIp=$(grep -Eo "172(.[[:digit:]]{1,3}){3}" <<< "${sshResultsArr[3]}") # find IP starting with 172
hasDockerIp=${hasDockerIp:="none"} # if not found IP set to "NONE"
printf "%s \t OS version: %s \t has Docker IP: %s\n" "$hostname" "$osVersion" "$hasDockerIp"
done
I was able to take a little bit from the answers I received and put together something that works well. Thank you all for your answers.
for host in "$#"
do
case "$host" in
('vho1uc1-primary'|'vho1uc2-backup'|'vho2uc1-primary'|'vho2uc2-backup'|'vho3uc1-primary'|'vho3uc2-backup'|'vho10uc1-primary')
var1=`ssh "$host" sudo /etc/init.d/apache2 status|awk '{print $4}'`
var2="$( echo $var1 | cut -c 3-5 )"
if [[ "$var2" == "$var3" ]]; then
echo "Apache2 on $host is running"
echo "0"
else
echo "Apache2 on $host is not running"
echo "2"
fi
;;
*)
esac
done

Inner loop won't break

code works but won't continue to run the loop stuck in the inner loop not sure where the problem is, or maybe port scan just takes alot of time
#!/bin/bash
up()
{
ping -c 1 $1 > /dev/null
[ $? -eq 0 ] && echo IP: $i is up.
}
for i in 192.168.0.{1..255}
do
up $i & disown
for port in {1..100};do
2>/dev/null echo > /dev/tcp/$i/$port
if [ $? == 0 ]
then
{
echo "port $port is open"
continue
}
fi
done
done
exit
Scan Ping + TCP in bash
I've tried to limit script to 8182 forks in order to stay polite.
This script scan /etc/services, then could scan all (desired) ports. (see comments).
Full scan of my complex private subnet take more than 5 minutes to complete (scanning 303 ports on 255 hosts, found 27 up)!
#!/bin/bash
BaseIP=${1:-192.168.1}
ports=(21 22 25 80 443 9100)
# ports=({1..100}) # Uncomment this for ports 1-100
while IFS=$' \t\r\n/' read serv port prot comm ;do
[ "$prot" = "tcp" ] && printf -v $prot[$port] %s "$serv"
done </etc/services
# ports=(${!tcp[#]}) # Uncomment this for all known ports
isup() { ping -W 1 -c1 -n $1 &>/dev/null && printf "IP: %-17sis up.\n" $1;}
tstport() { local _tst _prot=${3:-tcp}; local -n _var=$_prot[$2]
{
exec {_tst}<>/dev/$_prot/$1/$2 && exec {_tst}<&- &&
printf "IP: %-16s port %6d open (%s)\n" $1 $2 ${_var:-unassigned}
} 2>/dev/null
}
step=$((8180/(${#ports[#]}+1)))
for ((i=1;i < 255;i+=step)) {
max=$((i+step>255?255:i+step))
for ((l=i;l<max;l++)) {
isup $BaseIP.$l &
exec {dummy}< <(:)
for port in ${ports[#]} ;do
exec {dummy2}< <(:)
tstport $BaseIP.$l $port & read -u $dummy2 -t .02
exec {dummy2}<&-
done &
read -u $dummy -t .02
exec {dummy}<&-
} |
sed -une /./p
}
Sorted ouptut could look like:
IP: 192.168.1.1 is up.
IP: 192.168.1.3 is up.
IP: 192.168.1.3 port 22 open (ssh)
IP: 192.168.1.15 is up.
IP: 192.168.1.15 port 22 open (ssh)
IP: 192.168.1.15 port 139 open (netbios-ssn)
IP: 192.168.1.15 port 445 open (microsoft-ds)
IP: 192.168.1.15 port 515 open (printer)
IP: 192.168.1.39 is up.
IP: 192.168.1.39 port 22 open (ssh)

how to run multiple commands on a remote linux server using bash script

I am currently writing the following script that logs into a remote server and runs couple of commands to verify the performance of the server and prints a message based on the output of those commands .But the ssh doesn't work and returns the stats of the server that hosts the script instead .
Script
#!/bin/bash
#######################
#Function to add hosts to the array
#the following function takes the ip addresses provided while the script is run and stores them in an array
#######################
Host_storing_func () {
HOST_array=()
for i in $# ;do
HOST_array+=(${i});
done
#echo ${HOST_array[*]}
}
#######################
#Calling above function
#######################
Host_storing_func "$#"
############################################################
#Collect Stats of Ping,memory,iowait time test function
############################################################
b=`expr ${#HOST_array[*]} - 1 `
for i in `seq 0 $b` ;do
sshpass -f /root/scripts/passwordFile.txt /usr/bin/ssh student35#${HOST_array[${i}]} << HERE
echo `hostname`
iowaittm=`sar 2 2|awk '/^Average/{print $5};'`
if [ $iowaittm > 10 ];then
echo "IO ==> BAD"
else
echo "IO ==> GOOD"
fi
memoryy=`free -m |grep Swap|awk '{if($2 == 0) print 0;else print (($4 / $2 ) * 100)}'`
if [ ${memoryy} < '10' ] ;then
echo "memory ==> good"
elif [[ "${memory}" -ge 0 ]] && [[ "${memory}" -le 10 ]];then
echo "No Swap"
else
echo "memory ==> bad"`enter code here`
fi
ping -w2 -c2 `hostname` | grep "packet loss"|awk -F, '{print $3}'|awk -F% '{print $1}'|sed 's/^ *//'|awk '{if ($1 == 0) print "Yes" ;else print "No"}'
HERE
done
Output : oc5610517603.XXX.com is the name of the source server
[root#oc5610517603 scripts]# ./big_exercise.sh 9.XXX.XXX.XXX 9.XXX.XXX.XXX
Pseudo-terminal will not be allocated because stdin is not a terminal.
oc5610517603.XXX.com
IO ==> GOOD
No Swap
ping: oc5610517603.ibm.com: Name or service not known
Pseudo-terminal will not be allocated because stdin is not a terminal.
oc5610517603.XXX.com
IO ==> GOOD
No Swap
ping: oc5610517603.XXX.com: Name or service not known
thanks for checking the script , I figured out a way to solve the problem
It is the sshpass command that is causing issue , you just have to put the opening HERE in single quotes if you want to use variables with in the HEREdoc but if the variables are calculated before ssh then you don't have to put opening HERE in single quotes
sshpass -f /root/scripts/passwordFile.txt /usr/bin/ssh -T student35#${i} << 'HERE'
after I changed the sshpass command as above my script worked
I have modified your script a bit.
As suggested by #chepner, I am not using the Host_storing_func.
Heredocs for sshpaas are somewhat tricky. You have to escape every back-tick and $ sign in the heredoc.
Notice the - before the heredoc start, it allows you to indent the heredoc body. Also, try to avoid back-ticks when you can. use $(command) instead.
Hope it helps.
#!/bin/bash
#######################
#Function to add hosts to the array
#the following function takes the ip addresses provided while the script is run and stores them in an array
#######################
array=( "$#" )
user="student35"
############################################################
#Collect Stats of Ping,memory,iowait time test function
############################################################
for host in ${array[#]}; do
sshpass -f /root/scripts/passwordFile.txt /usr/bin/ssh -l ${user} ${host} <<-HERE
thishost=\$(hostname)
echo "Current Host -> \$thishost";
iowaittm=\`sar 2 2|awk '/^Average/{print \$5}'\`
if [ \$iowaittm > 10 ]; then
echo "IO ==> BAD"
else
echo "IO ==> GOOD"
fi
memory=\$(free -m | grep Swap | awk '{if(\$2 == 0) print 0;else print ((\$4 / \$2 ) * 100)}')
if [ \${memory} < '10' ] ;then
echo "memory ==> good"
elif [[ "\${memory}" -ge 0 ]] && [[ "\${memory}" -le 10 ]]; then
echo "No Swap"
else
echo "memory ==> bad"\`enter code here\`
fi
ping -w2 -c2 \`hostname\` | grep "packet loss"|awk -F, '{print \$3}'|awk -F% '{print \$1}'|sed 's/^ *//'|awk '{if (\$1 == 0) print "Yes" ;else print "No"}'
HERE
done

Shell script port scanner

I would like to scan multiple ports in multiple hosts. I used this script but it takes long time to show the result.
#!/bin/bash
hosts=(
"server1"
"server2"
)
for host in "${hosts[#]}"
do
echo "=========================================="
echo "Scanning $host"
echo "=========================================="
for port in {21,22,80}
do
echo "" > /dev/tcp/$host/$port && echo "Port $port is open"
done 2>/dev/null
done
Some people suggested to use telnet or NetCat instead but i prefer to do it without installing any new packages. So, are there any ways to speed it up by multithreading or other way.
You could use GNU Parallel to run all the checks in parallel. I am not the best at using it, and #OleTange (the author) normally has to correct me but I keep trying. So, let's try your case, by building up to it slowly:
parallel echo {1} {2} ::: 192.168.0.1 192.168.0.8 ::: 21 22 80
192.168.0.8 22
192.168.0.8 80
192.168.0.8 21
192.168.0.1 80
192.168.0.1 22
192.168.0.1 21
looks kind of hopeful to me. Then I add in -k to keep the results in order, and I supply a function that takes those IP addresses and ports as arguments:
parallel -k 'echo "" > /dev/tcp/{1}/{2} && echo {1}:{2} is open' ::: 192.168.0.1 192.168.0.8 ::: 21 22 80 2>/dev/null
192.168.0.1:80 is open
192.168.0.8:21 is open
192.168.0.8:22 is open
192.168.0.8:80 is open
This will run 8 jobs in parallel if your CPU has 8 cores, however echo is not very resource intensive so you can probably run 32 in parallel, so add -j 32 after the -k.
If you wanted to stick closer to your own script, you can do it like this:
#!/bin/bash
hosts=(
"192.168.0.1"
"192.168.0.8"
)
for host in "${hosts[#]}"
do
for port in {21,22,80}
do
echo "(echo > /dev/tcp/$host/$port) 2>/dev/null && echo Host:$host Port:$port is open"
done
done | parallel -k -j 32
Basically, instead of running your commands, I am just sending them to the stdin of parallel so it can do its magic with them.
You could run all three pokes in the background, then wait for them all to finish, and probably slash the running time to 1/3.
for port in 21 22 80; do
echo "" > /dev/tcp/$host/$port 2>/dev/null &
pid[$port]=$!
done
for port in 21 22 80; do
wait $pid[$port] && echo "Port $port" is open"
done
You could add parallelism by running multiple hosts in the background, too, but that should be an obvious extension.
#!/bin/bash
function alarm {
local timeout=$1; shift;
# execute command, store PID
bash -c "$#" &
local pid=$!
# sleep for $timeout seconds, then attempt to kill PID
{
sleep "$timeout"
kill $pid 2> /dev/null
} &
wait $pid 2> /dev/null
return $?
}
function scan {
if [[ -z $1 || -z $2 ]]; then
echo "Usage: ./scanner <host> <port, ports, or port-range>"
echo "Example: ./scanner google.com 79-81"
return
fi
local host=$1
local ports=()
# store user-provided ports in array
case $2 in
*-*)
IFS=- read start end <<< "$2"
for ((port=start; port <= end; port++)); do
ports+=($port)
done
;;
*,*)
IFS=, read -ra ports <<< "$2"
;;
*)
ports+=($2)
;;
esac
# attempt to write to each port, print open if successful, closed if not
for port in "${ports[#]}"; do
alarm 1 "echo >/dev/tcp/$host/$port" &&
echo "$port/tcp open" ||
echo "$port/tcp closed"
done
}
scan $1 $2

Bash script telnet to test multiple addresses and ports

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..
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.
A slight update to the accepted answer:
#!/bin/bash
# supertelnet 127.0.0.1:3306 10.10.10.45:22
(
TCP_TIMEOUT=3
for hostport in ${#}; do
a=(${hostport//:/ })
host=${a[0]}
port=${a[1]}
(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 ..."
I find this to be a lot more friendly as a script.
Pure bash nmap replacment:
Sorry for comming so late on this question.
Speed parallelized process
This could be a lot quicker if all probe are done together:
TargetList=(
scanme.nmap.org:21 scanme.nmap.org:22 scanme.nmap.org:23
scanme.nmap.org:79 scanme.nmap.org:80 scanme.nmap.org:81
)
checkTcpConn() {
local line testfd bpid=$BASHPID
( sleep 3 && kill -INT $bpid && echo $1 timeout) &
if exec {testfd}<>/dev/tcp/${1/:/\/};then
echo >&$testfd $'\r\n\r\n'
read -ru $testfd -t 1 line
[[ $line ]] &&
echo $1 open $line ||
echo $1 open
exec {testfd}<&-
else
echo $1 closed
fi
}
for target in ${TargetList[#]};do
checkTcpConn $target &
done 2>/dev/null | sort
will output quickly:
scanme.nmap.org:21 closed
scanme.nmap.org:22 open SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.13
scanme.nmap.org:23 closed
scanme.nmap.org:79 closed
scanme.nmap.org:80 open HTTP/1.1 400 Bad Request
scanme.nmap.org:81 closed
or worst:
for target in scanme.nmap.org:{{1..1024},3128,3306,5432,5900,8080};do
checkTcpConn $target &
sleep .002
done 2>/dev/null | grep open
scanme.nmap.org:22 open SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.13
scanme.nmap.org:80 open HTTP/1.1 400 Bad Request
And with a timeout:
for target in scanme.nmap.org:2{2,1} 192.168.210.123:1 ;do
checkTcpConn $target &
done 2>/dev/null |
sort
192.168.210.123:1 timeout
scanme.nmap.org:21 closed
scanme.nmap.org:22 open SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.13
Nota The last pipe done 2>/dev/null | sort is required in order to avoid job control messages. For showing raw output, use
...
done 2>/dev/null | cat

Resources