Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Q: Why does the second iteration exits after Can someone explain that? Or I just found a "while/netcat" bug?

a.txt's content:

$ cat a.txt

First iteration, this is ok, just outputs the file content:

$ while read oneline; do echo $oneline; done < a.txt

Second iteration, this is bad, it exists when coming to

$ while read oneline; do nc -w 3 "$oneline" 22 >& /dev/null; echo $oneline; done < a.txt

Exit codes:

$ nc -w 3 "" 22 >& /dev/null; echo $?
$ nc -w 3 "" 22 >& /dev/null; echo $?

So there is no SSH server behind But there is one behind But the "while" iteration shouldn't exit before going through all the lines, no? Why does it miss What am I missing here?

My main purpose is that I'm having a file (a.txt) that contains IP addresses. I need to sort these IP addresses in two files:

A) The ones that are reachable (ssh is prompting, so server is available)
B) The ones that are not reachable (timeout after 3 seconds, because there aren't anything listening on port 22)

"reachable" means that are there anything listening on port 22 behind the IP.

share|improve this question

2 Answers 2

up vote 3 down vote accepted

I think I have an answer: when nc tries an IP address that has a server listening on port 22 (which is typically SSH server), it reads the rest of the input and passes it to the server on port 22. The SSH server I have running on my home machines just eats the input.

The nc I have (Slackware 13.1 system) has a "-z" option, for "zero I/O". Try

nc -z -w 3 "$oneline" >& /dev/null

as the command in your while-loop. I think that other nc implementations exist. There's a GNU netcat for example, but it takes a "-z" option as well.

share|improve this answer
omg. it works. you're the god. –  LanceBaynes Jan 26 '12 at 4:00

May be it breaks that you have any special symbol at the end of You could try to analyze file without 'read' command:

HOSTS=`cat a.txt`
for host in $HOSTS; do 
    code=`nc -w 3 -z "$host" 22 >& /dev/null; echo $?`
    if [ "$code" == "0" ]; then 
        echo $host >> reachable.txt
        echo $host >> unreachable.txt
share|improve this answer
$HOSTS is HOSTS –  LanceBaynes Jan 26 '12 at 3:55
and "fi" is missing –  LanceBaynes Jan 26 '12 at 3:55
thank you, this one works too. –  LanceBaynes Jan 26 '12 at 4:00
Thanks for correction –  Sergei Lomakov Jan 26 '12 at 7:34

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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