Home > Net >  Bash Script to Automate Telnet
Bash Script to Automate Telnet

Time:07-23

I'm trying to automate telnet, using this command which works great

echo -e "\x1dclose\x0d" |
  telnet abc.gc.ca 100 |
  grep Connected>/dev/null && printf "PASSED\n" || printf "FAILED\n"

But if I put it in a script, it just hangs and I have no idea why.

#!/bin/bash

SERVERS=(
   "abc.gc.ca 100"
   "defg.gc.ca 101"
   "123.gc.ca 102"
   "xyz.gc.ca 103"
)

for host in ${SERVERS[@]}; do
  echo -e "\x1dclose\x0d" |
    telnet $host |
    grep Connected > /dev/null && printf "PASSED\n" || printf "FAILED\n"
done

CodePudding user response:

The big problem was with the array dereference: Using ${SERVERS[@]} without quotes around it was treating the port as a separate hostname.

#!/bin/bash
servers=(
   abc.gc.ca:100
   defg.gc.ca:101
   123.gc.ca:102
   xyz.gc.ca:103
)

for host_port in "${servers[@]}"; do
  host=${host_port%:*}   # put everything before the last : into host
  port=${host_port##*:}  # put everything after the last : into port
  if printf '\x1dclose\x0d' | telnet "$host" "$port" | grep -q Connected; then
    printf "PASSED\n"
  else
    printf "FAILED\n"
  fi
done

Other notes:

  • All-caps variable names are used for names meaningful to the shell or operating system; other names are reserved for use by applications (like your script!), so you should use lowercase names where possible.
  • foo && bar || baz is not identical to if foo; then bar; else baz; fi. For reliable code, use if -- not a short-circuiting ternary -- when you want the behavior of if.
  • Using grep -q causes grep not to emit any output, so you don't need to redirect that output.
  • echo -e is not reliable: even if the shell is 100% certain to be bash, if the shell is compiled or configured at runtime to provide an XPG-compatible echo (configuration that can be done through environment variables), echo -e may print -e on output instead of treating it as an argument.

All that said, consider using a dedicated port-scanning tool if this is intended for any kind of real-world use case. Such tools (nmap &c) can scan a large number of hosts in parallel without needing to run a subprocess for each, much less several subprocesses as used here.

CodePudding user response:

you can try with `/dev/tcp' file.

SERVERS=(
   "abc.gc.ca/100"
   "defg.gc.ca/101"
   "123.gc.ca/102"
   "xyz.gc.ca/103"
)

for host in ${SERVERS[@]}; do
     timeout 3 bash -c "cat < /dev/null > /dev/tcp/$host" &&
         echo "PASSED" || echo "FAILED"
done
  • Related