a part string is missing when echo in bash - bash

The bash script is:
echo Updating hostname and IP address ...
echo ${config_template_ip}
echo "ssh-keygen -R ${config_template_ip} -f /home/testusr/.ssh/known_hosts"
echo ${config_template_ip}
The output is
Updating hostname and IP address ...
10.100.224.250
-f /home/testusr/.ssh/known_hosts
10.100.224.250
why didn't "ssh-keygen -R ${config_template_ip} " on STDOUT, and how to solve that?

Related

Issue with ping sweep that reads in an IP address

The main issue I am having with this is pinging the read in IP address. It always says that the address is down.
Ping_Sweep()
{
echo -e '\n'
echo '----- Ping Sweep -----'
echo -e '\n'
command date >> pingresults.tx
echo "Enter in the first three number sequences of an IP address (ex. ###.###.###): "
read -r ip_address
for x in $ip_address
do
echo "IP address being pinged: $ip_address"
if ping –c 1 "$x" &> /dev/null
then
echo "IP: $x is up."
else
echo "Ping failed. $x is down."
fi
done
Main_Menu
}
ping –c should be ping -c. Your original command has an en dash. This is usually caused by copying code rendered by a bad blog framework.

BASH Script that loops thru 4 different text files

I'm trying to create a BASH script that takes data from four different text files and assigns each line from each of the text files to a variable and then run a command using those variables. I already have a for loop constructed to do this task but the challenge I'm having is the for loop isn't doing one on one mapping.
I want this loop to iterate thru every line and run the command once per line and stop the loop when it reaches the EOF. When I run this script, I get the output as follows;
The username is jsmith The hostname is 0000-Ubuntu The description is P-Ubuntu The IP is 0.0.0.0/24
The username is jsmith The hostname is 0000-Ubuntu The description is P-Ubuntu The IP is 1.1.1.1/24
The username is jsmith The hostname is 0000-Ubuntu The description is P-Ubuntu The IP is 2.2.2.2/24
I need this to be one one one mapped; for example:
The username is jsmith The hostname is 0000-Ubuntu The description is P-Ubuntu The IP is 0.0.0.0/24
The username is pstone The hostname is 1111-Ubuntu The description is P-Ubuntu The IP is 1.1.1.1/24
The username is drogers The hostname is 3333-Ubuntu The description is P-Ubuntu The IP is 3.3.3.3/24
and so on....
As you can tell, I'm a newbie in bash scripting and I'd really appreciate any guidance/help.
Thanks!
#!/bin/bash
HOSTNAMES=$(cat /home/squadri/hostnames.txt)
DESCRIPTIONS=$(cat /home/squadri/descriptions.txt)
USERNAMES=$(cat /home/squadri/usernames.txt)
IPS=$(cat /home/squadri/ips.txt)
for i in $HOSTNAMES ; do
for j in $DESCRIPTIONS ; do
for k in $USERNAMES ; do
for l in $IPS ; do
echo "The username is $k"
echo "The hostname is $i"
echo "The description is $j"
echo "The IP is $l"
done
done
done
done
You can use the paste command for that:
paste /home/squadri/{hostnames,descriptions,usernames,ips}.txt |\
while read hostname description username ip; do
echo "The username is $username"
echo "The hostname is $hostname"
echo "The description is $description"
echo "The IP is $ip"
done
One potential pitfall with this approach is whitespace characters in your files but it should work fine if there are none in any of the lines in your files.
Read from 4 different file descriptors:
while IFS= read -r hostname;
IFS= read -r description <&3;
IFS= read -r username <&4;
IFS= read -r ip <&5; do
echo "The username is $username"
echo "The hostname is $hostname"
echo "The description is $description"
echo "The IP is $ip"
done < hostnames.txt 3< descriptions.txt 4< usernames.txt 5< ips.txt
Technically, this reads until the end of descriptions.txt, regardless of the length of the other files. To stop when the shortest file ends, join the commands with &&:
while IFS= read -r hostname &&
IFS= read -r description <&3 &&
IFS= read -r username <&4 &&
IFS= read -r ip <&5; do
echo "The username is $username"
echo "The hostname is $hostname"
echo "The description is $description"
echo "The IP is $ip"
done < hostnames.txt 3< descriptions.txt 4< usernames.txt 5< ips.txt
Iterating until you reach the end of the longest file is a little more complex (you can't simply join the commands with ||), so I'll leave it as an exercise to the interested reader unless requested.

bash read does not wait for input

I have this code:
#!/bin/bash
for some_host in $(cat some_list); do
echo $some_host
ssh $some_host sudo cat /etc/some.conf |grep -i something_to_grep
printf "\nPut the input: " read some_input
echo $some_input
done
When I run it, it just continues without waiting for my input. I need to copy/past something form ssh output for further action :/
Change
printf "\nPut the input: " read some_input
to
read -p "Put the input: " some_input
Example
for host in '1.1.1.100' '1.1.1.101' '1.1.1.102'
do
read -p "Enter your input for ${host} " host_input
echo "${host} says ${host_input}"
done

Why is this while loop not looping?

I have the following bash script deploy.sh:
#!/usr/bin/env bash
# Some useful resources:
# while read ip user pass; do : http://unix.stackexchange.com/questions/92664/how-to-deploy-programs-on-multiple-machines
# -o StrictHostKeyChecking=no: http://askubuntu.com/questions/180860/regarding-host-key-verification-failed
# -T: http://stackoverflow.com/questions/21659637/how-to-fix-sudo-no-tty-present-and-no-askpass-program-specified-error
# echo $pass |: http://stackoverflow.com/questions/11955298/use-sudo-with-password-as-parameter
while read ip user pass; do
echo $ip
sshpass -p "$pass" ssh $user#$ip -o StrictHostKeyChecking=no -T "
echo 'yo'
"
echo 'done'
done < servers.txt
servers.txt contains:
53.12.45.74 my_username my_password
54.12.45.74 my_username my_password
57.12.45.74 my_username my_password
‌‌
From my understanding, the while read ip user pass; do […] done < servers.txt should loop over all three lines of servers.txt.
However, when I try to run it, it only performs one iteration:
ubuntu#server:~$ bash deploy.sh
53.12.45.74
yo
done
ubuntu#server:~$
Why?
If the loop is simply:
while read ip user pass; do
echo $ip
done < servers.txt
it does perform all three iterations:
ubuntu#server:~$ bash deploy.sh
53.12.45.74
54.12.45.74
57.12.45.74
ubuntu#server:~$
sshpass is taking control of stdin or possibly replacing it and causing while loop to lose input from redirected stdin.
To work around this issue, avoid reading from stdin.
First, load the file into an array using a while loop.
while read line; do
entries+=("$line")
done < servers.txt
Next, use for loop to parse the lines and execute sshpass within this loop.
for line in "${entries[#]}"; do
set $line
ip=$1
user=$2
pass=$3
echo $ip
sshpass -p "$pass" ssh $user#$ip -o StrictHostKeyChecking=no -T "
echo 'yo'
"
echo 'done'
done
The second loop doesn't read from stdin.
But I will recommend Rany Albeg Wein answer using a separate descriptor than the current stdin.
while read ip user pass <&3; do
echo $ip
sshpass -p "$pass" ssh $user#$ip -o StrictHostKeyChecking=no -T "
echo 'yo'
"
echo 'done'
done 3<servers.txt
#!/usr/bin/env bash
# Some useful resources:
# while read ip user pass; do : http://unix.stackexchange.com/questions/92664/how-to-deploy-programs-on-multiple-machines
# -o StrictHostKeyChecking=no: http://askubuntu.com/questions/180860/regarding-host-key-verification-failed
# -T: http://stackoverflow.com/questions/21659637/how-to-fix-sudo-no-tty-present-and-no-askpass-program-specified-error
# echo $pass |: http://stackoverflow.com/questions/11955298/use-sudo-with-password-as-parameter
while read ip user pass; do
if [ -n "$ip" ]; then
echo "IP[$ip] USER[$user] PASS[$pass]";
# dont forget to uncomment this two lines here:
#sshpass -p "$pass" ssh $user#$ip -o StrictHostKeyChecking=no -T "
#echo 'yo'
echo ""; # Just a blank line"
echo "done.";
else
echo "Empty value.";
fi
done < servers.txt
So, now it works.

How can I read an IP address from the user in a bash script?

if [ "$1" == "-s" ]; then
echo "Connecting to host.."
scp root#IP_ADDRESS:/private/var/mobile/Library/SMS/sms.db /private/var/mobile/Media/BackupSMS
echo " "
exit
fi
I need to ask user for a IP-address, that will then be placed where IP_ADDRESS is above. I'm new to scripts, but I'm trying.
How would I do this?
Use the built in read command
read IP_ADDRESS
or, if you want a nice prompt:
read -p "Enter ip address: " IP_ADDRESS
and then add a $ to the scp line:
scp root#$IP_ADDRESS:/...
^

Resources