Need Help ssh key fail on remote server

Hello everyone,
I need some help writing a bash script to:

  1. ssh from a jumpserver to 50 remote servers logging in automatically using ssh keys and capture if zabbix is running by running a "ps -ef | grep zabbix" and output to a logfile capturing the server hostname and ps -ef output to determine if zabbix is running.
  2. I need the script to move on to the next server if ssh keys are not working and it asks for a password. It would be nice to have output to a log file all the servers where ssh keys are not working so I can go and fix the those servers later.

The problem I am having now is the script hangs on a server whenever the ssh keys dont work. So I really need some bash code for the script to skip to next server when this happens. I believe I need an if then statement script but cant figure out the exact syntax.

Here is what I have so far:

#!/bin/bash
for x in `cat server_list`;do echo $x>>zab_chk_output.txt; ssh $x ps -ef | grep zabbix>>zab_chk_output.txt
done

Appreciate everyone's help with this and thanks!
-vtowntechy

Something like this...

for server in $(cat server_list);do
  {
  # set a different connect and command timeout ( you probably want to know the difference 
  # between an unreachable server and an unconfigured keybased authentication)
  output=$(timeout 10 ssh -o ConnectTimeout=8 $server ps -ef \| grep [z]abbix)
  code=$?
  if [ $code -ne 124 ]; then # return code 124 is the code when timeout has been reached
   echo "$server auth ok::$code::$output"
 else
   echo "$server auth failed" 
 fi
 } # Add a & before the # if you want to have all ssh connections started in parallel
done >zab_chk_output.txt
wait
1 Like

Some comments:
A timeout binary exists on some Linux platforms. There are also some timeout scripts available for download.
ConnectTimeout is a nice option on a recent openssh.
The [ ] needs to be escaped, otherwise the shell tries to find matches in the current directory (and would substitute it with a matching file name).
Because it is interpreted/substituted again on the remote host, it needs to be double-escaped.

 output=$(timeout 10 ssh -o ConnectTimeout=8 $server 'ps -ef | grep -w "[z]abbix"')

A word match grep -w is more precise.
Most precise would be pgrep -x that exists on Linux and some Unix platforms.

 output=$(timeout 10 ssh -o ConnectTimeout=8 $server 'pgrep -x zabbix')

--
The for-do-done is a block. So you don't need another { block } around it only to redirect its input or output.

1 Like