1

Im trying to create a rather basic script to run through a list of servers and check if the SSH port is open using nc. I've tried a few different ways, but can't seem to get this to work. I am definitely not great at any type of scripting.

Here is the script. I just want it to perform an action if it sees "succeeded" in the response from the nc command in OPEN.

while read SERVER
do
OPEN=$(nc -z -v -w5 $SERVER 22)
echo $SERVER
   if [[ $OPEN = *"suc"* ]];
    then
        echo "Found SSH open on $SERVER"
    else
        echo "No open ports on $SERVER!"    
   fi
done < server.txt

The list of servers is in the server.txt file that is referenced at the end on the script.

Here is the response that I get. I not

nc: connect to 10.10.51.55 port 22 (tcp) failed: No route to host
10.10.51.55
No open ports on test1!
Connection to 10.10.51.65 22 port [tcp/ssh] succeeded!
10.10.50.65
No open ports in test2!

It give me the "No open ports on $SERVER" no matter what.

I thank you for any guidance.

3
  • Did you actually check the value of OPEN? you're capturing standard output - but I suspect the ... succeeded! message from nc is on the standard error stream – steeldriver May 10 '18 at 23:16
  • I hope the issue with ur server.txt try giving ipaddress. – Siva May 10 '18 at 23:18
  • @steeldriver thank you my friend -- you have helped me. That was it :) – saleetzo May 10 '18 at 23:23
3

Notes, too long for a comment.

  1. server.txt could better be named server-list or servers.txt if you wish.

  2. Use lower case variable names like, avoid SERVER and alike, could better be named server_ip anyways, because it is unclear if you use host names or IPs.

  3. Double quote all non-integer-number variables like "$server_ip".

  4. Use a direct if statement instead of variable $OPEN with a redirection to the black hole (/dev/null).


Rewritten based on above:

#!/bin/sh

while read server_ip
do

    if nc -z -v -w5 "$server_ip" 22 > /dev/null 2>&1
    then
        echo "Found SSH port open on $server_ip."
    else
        echo "Did not find open SSH port on $server_ip."
    fi

done < server-list
0
3

The most simple solution seems to be:

if nc -z -v -w5 $SERVER 22 >/dev/null 2>&1;
then
    echo "Found SSH open on $SERVER"
else
    echo "No open ports on $SERVER!"    
fi
1

The issue is that nc writes to standard error when outputting diagnostic messages, while a command substitution only captures standard output.

You also should be using == in [[ ... ]]. Variable expansions should be quoted and ideally you'd be using printf to output variable data.

This means that you code could look like

while read SERVER do
    OPEN=$( nc -z -v -w5 "$SERVER" 22 2>&1 )
    if [[ "$OPEN" == *succ* ]]; then
        printf 'Found SSH open on %s'\n' "$SERVER"
    else
        printf 'No open ports on %s!\n' "$SERVER"    
    fi
done <server.txt

or

while read SERVER do
    OPEN=$( nc -z -v -w5 "$SERVER" 22 2>&1 )
    case "$OPEN" in
        *succ*) printf 'Found SSH open on %s'\n' "$SERVER" ;;
        *)      printf 'No open ports on %s!\n' "$SERVER"  ;;
    esac
done <server.txt

Or, you could just use the exit status of nc:

while read SERVER do
    if nc -z -v -w5 "$SERVER" 22 >/dev/null 2>&1; then
        printf 'Found SSH open on %s'\n' "$SERVER"
    else
        printf 'No open ports on %s!\n' "$SERVER"
    fi
done <server.txt
1
  • Thanks for the tips and also the different ways of completing my task. This has helped me through teaching as well. – saleetzo May 11 '18 at 17:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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