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 toif foo; then bar; else baz; fi
. For reliable code, useif
-- not a short-circuiting ternary -- when you want the behavior ofif
.- Using
grep -q
causesgrep
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-compatibleecho
(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