0
\$\begingroup\$

A Few years back I used to opt the below method to run the shell program in a Parallel way to open multiple ssh session at a time to get a quick result.

I know there are various other good utilities available, however due to some pressing needs I've to use this way, this dirty piece of code works well however I would like to know if there are some suggestion to improve it further considering the fact I have to use it for some compelling reasons over other better tools.

#!/bin/bash
echo "$(date) Starting the SSH Connection Check...."
#set -x

read -rsp $'Please Enter password below: ' SSHPASS
export SSHPASS
SSH_Connection () {
    hostTarget=${1}
    sshpass -e ssh -q "${hostTarget}" "true" -o StrictHostKeyChecking=no -o ConnectTimeout=60 2>>/dev/null
    if [[ $? -eq 0 ]]
    then
        echo  "$CurrntTime $MachineName   : SSH connection is Up"
    elif [[ $? -eq 255 ]]
        then
        echo  "$CurrntTime $MachineName   : SSH Authentication Failed"
    elif [[ $? -eq 2 ]]
        then
        echo  "$CurrntTime $MachineName   : SSH connection is Down"
    elif [[ $? -eq 1 ]]
        then
        echo  "$CurrntTime $MachineName   : SSH Authentication Failed"
    else
        echo  "$CurrntTime $MachineName   : SSH connection is Down"
    fi
}

HostList=$(<~/host2)

CurrntTime=$(date +'%m/%d/%Y %T')

for MachineName in ${HostList}
do
    SSH_Connection "${MachineName}" &
done
# wait for all outstanding background jobs to complete before continuing
wait
# at last clear the exported variable containing the password
unset SSHPASS
\$\endgroup\$
2
  • \$\begingroup\$ Do you have compelling reasons for not using ssh keys? digitalocean.com/community/tutorials/… \$\endgroup\$
    – chicks
    Feb 17, 2021 at 21:28
  • \$\begingroup\$ Yes.. I can not supply keys even. I know about ssh keys and another methods as well even about pssh but as i mentioned, its not always where we have liberty to choose our freedom over companies policies for any reasons. \$\endgroup\$
    – Karn Kumar
    Feb 18, 2021 at 4:23

1 Answer 1

2
\$\begingroup\$

The only part I would change are the chained if statements. Use case:

CurrntTime="some_timestamp"
MachineName="some_host"
for retval in 0 255 2 1 8; do
   echo "Testing exitcode ${retval}"
   case ${retval} in
   0)
        echo  "$CurrntTime $MachineName   : SSH connection is Up";;
   255)
        echo  "$CurrntTime $MachineName   : SSH Authentication Failed";;
   2)
        echo  "$CurrntTime $MachineName   : SSH connection is Down";;
   1)
        echo  "$CurrntTime $MachineName   : SSH Authentication Failed";;
   *)
        echo  "$CurrntTime $MachineName   : SSH connection is Down";;
   esac
done

More optimisation is not needed. The alternative beneath is slightly shorter but makes the code harder to read (more fun, though):

CurrntTime="some_timestamp"
MachineName="some_host"

ssh_err_0="connection is Up"
ssh_err_1="Authentication Failed"
ssh_err_2="connection is Down"
ssh_err_255="Authentication Failed"
ssh_err_other="connection is Down"

for retval in 0 255 2 1 8; do
   echo "Testing exitcode ${retval}"
   printf "%s" "$CurrntTime $MachineName   : SSH "
   case ${retval} in
   0|1|2|255)
      message="ssh_err_${retval}"
      echo "${!message}";;
   *)
      echo "${ssh_err_other}";;
   esac
done

When you use the first case in the total script, and move the SSH_Connection() function to the start of the script, it would be

#!/bin/bash

SSH_Connection () {
    hostTarget=${1}
    sshpass -e ssh -q "${hostTarget}" "true" -o StrictHostKeyChecking=no \
       -o ConnectTimeout=60 2>/dev/null

    case $? in
    0)
       echo  "$CurrntTime $hostTarget: SSH connection is Up";;
    255)
       echo  "$CurrntTime $hostTarget: SSH Authentication Failed";;
    2)
       echo  "$CurrntTime $hostTarget: SSH connection is Down";;
    1)
       echo  "$CurrntTime $hostTarget: SSH Authentication Failed";;
    *)
       echo  "$CurrntTime $hostTarget: SSH connection is Down";;
    esac
}

echo "$(date) Starting the SSH Connection Check...."

read -rsp $'Please Enter password below: ' SSHPASS
export SSHPASS

HostList=$(<~/host2)

CurrntTime=$(date +'%m/%d/%Y %T')

for MachineName in ${HostList}; do
   SSH_Connection "${MachineName}" &
done
# wait for all outstanding background jobs to complete before continuing
wait
# at last clear the exported variable containing the password
unset SSHPASS

I did not move the CurrentTime=$(..) inside the function. When you want to see the date/time after the ssh is finished, then you will need to store the exit code in a variable:

...
sshpass -e ssh ...
retval=$?
CurrentTime=$(date +'%m/%d/%Y %T')
case ${retval} in ...
\$\endgroup\$
2
  • \$\begingroup\$ Thanks Walter, How the complete code would look like then, can your formulate the code with you adjustment. \$\endgroup\$
    – Karn Kumar
    Mar 23, 2021 at 17:48
  • \$\begingroup\$ Is the code clear for you? \$\endgroup\$
    – Walter A
    Apr 14, 2021 at 19:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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