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 Commented May 10, 2018 at 23:16
  • I hope the issue with ur server.txt try giving ipaddress.
    – Siva
    Commented May 10, 2018 at 23:18
  • @steeldriver thank you my friend -- you have helped me. That was it :)
    – saleetzo
    Commented May 10, 2018 at 23:23

3 Answers 3

4

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 -r 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." >&2
    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 your code could look like

while IFS= read -r 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 IFS= read -r 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 IFS= read -r 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
4
  • Thanks for the tips and also the different ways of completing my task. This has helped me through teaching as well.
    – saleetzo
    Commented May 11, 2018 at 17:23
  • Why should they be using ==? That's just an alias for =. In [[...]], there's no need to distinguish between assignment and comparison (well, pattern matching here), there's no need for ==. You may be confusing with (( a = b )) (assignment) vs (( a == b )) (arithmetic comparison). Commented Apr 8, 2022 at 10:55
  • Beware the behaviour of read SERVER is dependent on the current value of $IFS. For instance, with IFS=m, read server on google.com stores google.co into $server. Commented Apr 8, 2022 at 10:56
  • @StéphaneChazelas I'm using == in [[ ... ]], and I'm only ever using [[ ... ]] when I need to, e.g. for pattern matching. It's personal style. The read issue will be fixed ASAP.
    – Kusalananda
    Commented Apr 8, 2022 at 11:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .