0

I need to check if telnet is happening or not on multiple remote servers.

I wrote a while loop to SSH over multiple remote servers and triggers an email whenever the telnet fails. But the issue is while loops iterates only over the first server and exits out of the script without reading remaining servers. Below is my shell script

#!bin/bash
while read  host_details
do

USERNAME=$(echo $host_details | awk -F"|" '{print $1}')
HOSTIP=$(echo $host_details | awk -F"|" '{print $2}')
PORT=$(echo $host_details | awk -F"|" '{print $3}')
PROXY=$(echo $host_details | awk -F"|" '{print $4}')
PROXY_PORT=$(echo $host_details | awk -F"|" '{print $5}')

STATUS=$(ssh -n  ${USERNAME}@${HOSTIP} -p${PORT} "timeout 4 bash -c \"</dev/tcp/${PROXY}/${PROXY_PORT}\"; echo $?;" < /dev/null)

if [ "$STATUS" -ne 0 ]
then
  echo "Connection to $PROXY on port $PROXY_PORT failed"
  mutt -s "Telnet connection to $PROXY on port $PROXY_PORT failed" abc.def@xyz.com
  
else
  echo "Connection to $PROXY on port $PROXY_PORT succeeded"
  mutt -s "Telnet connection to $PROXY on port $PROXY_PORT succeeded" abc.def@xyz.com
  
fi

done<.hostdetails

I observed my script works only when I remove IF condition and my while loops iterates over all the servers as expected.

Can anyone suggest why when I use IF condition the script exits after first iteration? And how to make it work and get the email alerts?

brooks619
  • 1
  • 2
  • 2
    `mutt` is probably reading the rest of the file; it's really intended for interactive use, so I'd recommend using a different mail program. Also, I recommend using lower- or mixed-case variables to avoid conflicts with the all-caps names with special meanings, and using `while IFS="|" read username hostIP ...` to split the fields instead of all those `awk` calls (see [BashFAQ #1](http://mywiki.wooledge.org/BashFAQ/001#Field_splitting.2C_whitespace_trimming.2C_and_other_input_processing)). [shellcheck.net](https://www.shellcheck.net) will have other good suggestions. – Gordon Davisson Jun 21 '21 at 07:47
  • `mutt` is the only choice I have in the server for me – brooks619 Jun 21 '21 at 08:24
  • Then try redirecting its input from /dev/null (like you're doing with `ssh`). – Gordon Davisson Jun 21 '21 at 08:29
  • You are correct, `mutt` is the culprit here. I am passing only "subject" but not the "body". Hence `mutt` is going in the interactive mode in the script. Now I have added the content to the email "body". It is now working perfectly. Thank you so much @GordonDavisson – brooks619 Jun 21 '21 at 08:40
  • You should add the full solution as an answer, so if someone else runs into the same problem later it'll be easy for them to use (but fix the other things I pointed out first, so the answer has cleaner code). – Gordon Davisson Jun 21 '21 at 08:43
  • Yes, updated the working solution with the suggested points. Thanks! – brooks619 Jun 21 '21 at 08:59
  • 1
    Please post the solution as an answer, rather than as an edit to the question; that way, you can mark it as "accepted" (after a 48-hour delay, I think), and the stackoverflow system will know that the question has been solved. See [this help entry](https://stackoverflow.com/help/self-answer). – Gordon Davisson Jun 21 '21 at 09:12

1 Answers1

0

Thanks to @GordonDavisson recommendation.

The mutt in the script is treating the remaining server details as an input list, hence the script is getting terminated after reading the first server values.

Replace mutt with another email program in your script. However, users who wish to go with mutt, then it is recommended to add content to their email body or redirect the stdin from mutt to /dev/null

Below is the working solution:

#!bin/bash

while IFS="|" read -r userName hostIp Port Proxy proxyPort
do

STATUS=$(ssh -n -tt -o LogLevel=quiet ${userName}@${hostIp} -p${Port} 'timeout 4 /bin/bash -c' \'"</dev/tcp/${Proxy}/${proxyPort}"\'; echo $? < /dev/null | tr -d '\r')
if [ "$STATUS" -ne 0 ]
then
  echo "Connection to $Proxy on port $proxyPort failed" | mutt -s "${hostIp}:Telnet connection to $Proxy on port $proxyPort failed" abc.def@xyz.com
else
  echo "Connection to $Proxy on port $proxyPort succeeded" | mutt -s "${hostIp}:Telnet connection to $Proxy on port $proxyPort succeeded" abc.def@xyz.com
fi
done<.hostdetails

The trim command in the solution is to delete the carriage return(\r) I was getting in the variable(STATUS)

brooks619
  • 1
  • 2