I'm working on a Bash/expect script to run show commands on multiple networking devices.
To identify the devices there are 2 acceptable options:
- IP Address
- Hostname -> The IP for this will be grepped from an inventory file.
My code:
#!/bin/bash
echo -e "\033[101mInsert the hostnames then hit Ctrl+D\033[0m"
cat > /temp.txt
echo
echo -e "\033[105mInsert the commands then hit Ctrl+D\033[0m"
cat > /commands.txt
echo
read -r -p $'\033[100mChoose what kind of check you would like to perform (\033[92mpre\033[39m or \033[35mpost\033[39m):\033[0m\n' prepost
prepost=${prepost:-pre}
username="uuuuuu"
pass="passssss"
############# Generate Expect Script ###########################################
echo "
#!/usr/bin/expect
set timeout 60
set hostname [lindex \$argv 0]
set username [lindex \$argv 1]
set password [lindex \$argv 2]
set send_slow {10 .001}
send_user \"\n#####\n# \$hostname\n#####\n\"
spawn ssh -oStrictHostKeyChecking=no \$username@\$hostname
expect {
timeout { send_user \"\nFailed to get password prompt\n\"; exit 1 }
eof { send_user \"\nSSH failure for \$hostname\n\"; exit 1 }
\"*#\" {}
\"*assword:\" {
send \"\$password\r\"
}
}
expect {
default { send_user \"\nCould not get into enabled mode. Password problem?\n\"; exit 1 }
\"*#\" {}
\"*>\" {
send \"ena\r\"
expect \"*assword\"
send \"\$password\r\"
}
}
expect \"*#\"
send \"term len 0\r\"
" >> /generated_expect
while read -r command
do
echo "
send \"$command\r\"
expect \"*#\"
" >> /generated_expect
done < /commands.txt
echo "expect \"*#\"
send \"!\r\"
send \"exit\r\"
close
" >> /generated_expect
chmod 700 /generated_expect
############################################################################################
echo
echo "#################################################################################"
echo
while read -r line
do
match=$(grep -i -m 1 "$line" /inventory.csv | cut -f1 -d";")
pattern="[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"
if [[ $line =~ $pattern ]]; then
host="$line"
echo Logging into "$host"
nohup /generated_expect "$host" "$username" "$pass" >> /"$line"_"$prepost".txt
echo
echo -e "\033[42m\033[30m Output successfully collected\033[39m\033[0m \n"
echo "--------------------------------------------------------------------------------"
else
if [[ $match =~ $line ]]; then
host=$(grep -i -m 1 "$line" /inventory.csv | cut -f2 -d";")
hostname=$(grep -i -m 1 "$line" /inventory.csv | cut -f1 -d";")
echo Logging into "$hostname"
nohup /generated_expect "$host" "$username" "$pass" >> /"$line"_"$prepost".txt
echo
echo -e "\033[42m\033[30m Output successfully collected\033[39m\033[0m \n"
echo "--------------------------------------------------------------------------------"
else
echo 0 match found for "$line"
fi
fi
done < /temp.txt
echo
rm /temp.txt
rm /commands.txt
rm /generated_expect
I've migrated this script from Ubuntu - where it was working perfectly - to my Mac.
This is the error I'm getting:
#####
# 1.1.1.1
#####
spawn ssh -oStrictHostKeyChecking=no uuuuuu@1.1.1.1
ssh: Could not resolve hostname 1.1.1.1^M: nodename nor servname provided, or not known
SSH failure for 1.1.1.1
I suspected that it has to do with line ending somewhere, but I cannot find it... I've checked everything, twice.
I know that the script itself if not the most elegant way to achieve the task I'm trying to do, but it was working good enough before. Any suggestion would be appreciated.
--- UPDATE ---
I've used ShellCheck as suggested; was able to clean the code a bit, but the error remans the same.
I've even tried the sed -i "" 's/\r$//' script.sh
which was suggested, but no luck there either.