0

I want to telnet some ips and I want to get the result of $? immediately: SO I tried:

while read ip; do
    telnet $ip 1>/dev/null 2>&1
    pkill $!
    if [ "$?" -eq "1" ]; then
       echo $ip >> host-ok
    fi
done < file

But this is not a good idea because when a telnet connection can't be established it doesn't work. and always the out put of $? would be correct.

I want to be sure telnet is going to be established and then kill the process. So if telnet is established after that I want to echo $ip to a file.

Any other solutions are welcome

Thank you

MLSC
  • 5,872
  • 8
  • 55
  • 89
  • what do you mean? no I don't use `expect` command becase maybe it has anything as login auth. if you telnet to correcy host then cntrl +c it immediately and wrong host then echo $? you can understand the difference – MLSC Jun 01 '14 at 07:30

3 Answers3

2

The code as written doesn't work because the telnet command is not backgrounded - pkill $! will always fail, because process $! no longer exists when you reach that line. You need to append an ampersand & at the end of the line to do that. You also need a timeout before killing the process, otherwise it won't have time to try to connect before stopping it. sleep 1 (or 5, or 60, depending on your use case) should take care of that.

You also want to use kill rather than pkill.

An alternative method which is probably much more robust is to avoid the killing altogether, and simply try to connect and quit immediately (similar to @PeteyT's answer):

while read ip; do
    printf '%bquit\n' '\035' | telnet "$ip" 1>/dev/null 2>&1
    if [ $? -eq 0 ]; then
       echo "$ip" >> host-ok
    fi
done < file

That should use the telnet default timeout (I don't know how long that is). If you want a configurable timeout you could try netcat.

l0b0
  • 55,365
  • 30
  • 138
  • 223
  • Thank you @l0b0. could you possibly show me how? because doesn't work but logicaly is true – MLSC Jun 01 '14 at 07:40
  • the previous one was correct. but now: If a telnet connection can't be established it writes: `trying x.x.x.x ... ` If we could send `cntrl + c` it would be better I think – MLSC Jun 01 '14 at 07:52
  • Why? Most applications handle [SIGTERM](https://en.wikipedia.org/wiki/Kill_%28command%29) and SIGINT identically. – l0b0 Jun 01 '14 at 07:54
  • 1
    Thank you. How do you see `echo "exit" | nc x.x.x.x 23 -w 3`? if I can telnet it exits and $?=0 if I can't telnet after 3s it exits and $?=1 – MLSC Jun 01 '14 at 07:58
  • Try it and see how it goes. – l0b0 Jun 01 '14 at 07:59
  • `nc` idea was the fastest and most reliable solution in the eyes of me – MLSC Jun 01 '14 at 08:22
1
 while read ip; do
   printf '%bquit\n' '\035' | telnet $ip 1>/dev/null 2>&1
   kill $!
   if [ $? -eq "1" ]; then
     echo $ip >> host-ok
   fi
 done < file
ptierno
  • 9,534
  • 2
  • 23
  • 35
  • Is it correct? ` pkill 035'$!` I think it is missing sth – MLSC Jun 01 '14 at 07:32
  • that was a typo. point is. all i did was show you how to send the escape sequence '^[' to telnet. – ptierno Jun 01 '14 at 07:37
  • Thank you. but I have IP when I telnet it the result is `Trying x.x.x.x ...`. how can I discard waiting to these issues – MLSC Jun 01 '14 at 07:39
  • @MortezaLSC this may be something for you to read? http://stackoverflow.com/questions/21424985/linux-bash-timer – ptierno Jun 01 '14 at 07:53
0

This is the fastest and the most reliable solution in the eyes of me:

LIST=$1
while read ip;do
    echo "exit" | nc "$ip" 23 -w 5
    if [ "$?" -eq "0" ]; then
        echo "$ip" >> host-ok
    fi
done < $LIST

Using nc rather than telnet is faster.

MLSC
  • 5,872
  • 8
  • 55
  • 89