1

I'm trying to check all servers in an array to see whether they are configured with the SSH password-less trust or not.
If some are not, I'd like to print the server details, and keep looping through the array elements (ips) until all have been checked.
(I want to have the opportunity to print all the erroneous ones before exiting.)

I tried the following approach, but it exits the loop after it meets the first unconfigured server:

for svr in "${table[@]}"
do
SSH=$(ssh -o PasswordAuthentication=no -o StrictHostKeyChecking=no $svr echo)

if $(echo [ $? -ne 0 ])
then echo "Trust is not configured for ${table[$svr]}"
    exit "$SOME"
else 
    :
fi
done

What am I doing wrong?

SherylHohman
  • 12,507
  • 16
  • 70
  • 78
faceless
  • 366
  • 1
  • 10
  • 1
    `if $(echo [ $? -ne 0 ])` looks unusual. Also see [How to check the exit status using an if statement using Bash](https://stackoverflow.com/q/26675681/608639). – jww Aug 12 '18 at 05:47
  • @jww - thanks for the info – faceless Aug 12 '18 at 06:23

1 Answers1

1

Well, the immediate problem is that you have an exit command in the middle of the loop... which will in fact exit the script when it hits that point. If you don't want it to exit until the loop has finished running, put the exit command after the loop.

But you're also checking whether ssh succeeded in a really weird way. Unless there's something I don't understand involved, just put the ssh command directly in the if condition, and discard its output with >/dev/null 2>&1:

for svr in "${table[@]}"
do
    if ssh -o PasswordAuthentication=no -o StrictHostKeyChecking=no $svr echo >/dev/null 2>&1
    then
        echo "Trust is not configured for $svr"
    fi
done

exit "$SOME"

Note that I also fixed the reference to ${table[$svr]} (which doesn't make sense), and removed the else clause (which wasn't doing anything). Also, what's $SOME?

EDIT: If you want it to exit if any of the server connections fail, you need to keep track of whether there's been a failure as the loop runs, then use that to control whether it exits at the end.

failures=0
for svr in "${table[@]}"
do
    if ssh -o PasswordAuthentication=no -o StrictHostKeyChecking=no $svr echo >/dev/null 2>&1
    then
        echo "Trust is not configured for $svr"
        ((failures++))
    fi
done

if ((failures>0))
then
    exit
fi
Gordon Davisson
  • 95,980
  • 14
  • 99
  • 125
  • Your rewrite incorrectly makes the exit unconditional. – Ben Voigt Aug 12 '18 at 06:07
  • @BenVoigt My understanding is that it's supposed to exit after checking all servers, whether or not any/all fail. If that's not the case, the question needs clarification. – Gordon Davisson Aug 12 '18 at 06:24
  • @GordonDavisson Ben Voight is right - i need to exit only if there is at minimum 1 error. If not - proceed to the next function. – faceless Aug 12 '18 at 06:28
  • @GordonDavisson thanks, will test now. Can you please explain the approach? P.S. - The veird way i'm testing the SSH has a reason: this test allows me to have the actual system reject reason and not only the printed output (Permission denied (publickey,password).) – faceless Aug 12 '18 at 06:41
  • @faceless what do you mean by the "actual system reject reason"? If you mean the ssh command's exit status, you can capture that with `$?` in the first command in the `then` section. You can also use `if sshoutput=$(ssh ... 2>&1)` to capture the error text from ssh as well as testing its exit status. – Gordon Davisson Aug 12 '18 at 07:44