0

I am trying to create a loop that'll store the output of an ssh command for each host in the list.

the code:

#!/bin/bash

while read i; do
        ip=$(echo "$i" | awk -F "\"*,\"*" '{print $2}') #(file contains name,ip values)

        if echo "$i" | grep -q "ARISTA"; then
                results=$(sshpass -f/root/cred ssh user@$ip "show running-config")
                echo "$results"
        elif echo "$i" | grep -q "NEXUS"; then
                results=$(sshpass -f/root/cred ssh user@$ip "show running-config")
                echo "$results"
        elif echo "$i" | grep -q "ARUBA"; then
                results=$(sshpass -f/root/cred ssh user@$ip "show running-config")
                echo "$results"
        elif echo "$i" | grep -q "R1"; then
                results=$(sshpass -f/root/cred ssh user@$ip "show configuration | display set")
                echo "$results"
        elif echo "$i" | grep -q "HP"; then
                results=$(sshpass -f/root/cred ssh user@$ip "display current-configuration")
                echo "$results"
        else
                echo "$i not found"
        fi
done </root/hosts.txt

The output I'm getting is a results of the first host in the list only. I suspect that the problem is sshpass due to the accurate results I receive when I try a different statement like:

#!/bin/bash

while read i; do
        ip=$(echo "$i" | awk -F "\"*,\"*" '{print $2}') #(file contains name,ip values)

        if echo "$i" | grep -q "ARISTA"; then
                echo "$ip = Arista"
        elif echo "$i" | grep -q "NEXUS"; then
                echo "$ip = Nexus"
        elif echo "$i" | grep -q "ARUBA"; then
                echo "$ip = Aruba"
        elif echo "$i" | grep -q "R1"; then
                echo "$ip = R1"
        elif echo "$i" | grep -q "HP"; then
                echo "$ip = HP"
        else
                echo "$i not found"
        fi
done </root/hosts.txt

Yet the loop breaks after the first sshpass command being executed.

Any ideas?

Saisuk
  • 5
  • 2
  • 1
    The files involve has a carriage returns or most likely [ssh pass is eating stdin](https://stackoverflow.com/questions/13800225/while-loop-stops-reading-after-the-first-line-in-bash), which both falls into a duplicate post/question. – Jetchisel Oct 19 '22 at 14:38
  • 1
    This doesn't strip the double quotes, but you can greatly simplify your code with something like: `while IFS=, read name ip values; do case $ip in *ARISTA*) echo "$ip = Arista";; *NEXUS*) echo "$ip = Nexus";; *ARUBA*) echo "$ip = Aruba";; *R1*) echo "$ip = R1";; *HP*) echo "$ip = HP";; *) echo "$name $ip $values not found";; esac; done< /root/hosts.txt`. Stripping the double quotes is pretty trivial – William Pursell Oct 19 '22 at 14:49
  • Why don't you setup public key authentication to those hosts instead of using ssh pass? – treuss Oct 19 '22 at 16:35

1 Answers1

0

Ok so.

This is the solution:

#!/bin/bash

while read i; do
        ip=$(echo "$i" | awk -F "\"*,\"*" '{print $2}') #(file contains name,ip values)

        if echo "$i" | grep -q "ARISTA"; then
                results=$(sshpass -f/root/cred ssh -n user@$ip "show running-config")
                echo "$results"
        elif echo "$i" | grep -q "NEXUS"; then
                results=$(sshpass -f/root/cred ssh -n user@$ip "show running-config")
                echo "$results"
        elif echo "$i" | grep -q "ARUBA"; then
                results=$(sshpass -f/root/cred ssh -n user@$ip "show running-config")
                echo "$results"
        elif echo "$i" | grep -q "R1"; then
                results=$(sshpass -f/root/cred ssh -n user@$ip "show configuration | display set")
                echo "$results"
        elif echo "$i" | grep -q "HP"; then
                results=$(sshpass -f/root/cred ssh -n user@$ip "display current-configuration")
                echo "$results"
        else
                echo "$i not found"
        fi
done </root/hosts.txt

Explanation is as Jetchisel suggests, ssh is eating STDIN. Therefore the solution is adding flag -n to the ssh command which will pass the output to /dev/null.

Much appreciated guys, have a good one.

Saisuk
  • 5
  • 2