Problem when using the ssh-copy-id command in script - linux

I write this for add SSH connection from the list automatically but when I run this script have error! I think this problem relate to read ip from $line variable in script.
My Script:
#!/bin/bash
filename='iplist.txt'
n=1
USER=root
SSHPASS=123456
while read line; do
echo "No. $n : IP = $line"
echo "yes \n" | sshpass -p "$SSHPASS" \
ssh-copy-id -o StrictHostKeyChecking=no $USER#$line \
&& echo "Add successfully!" || echo "FAILED"
echo "########################################"
n=$((n+1))
sleep 2
done < $filename
iplist.txt is a file that's contain my IPs:
172.25.25.1
172.25.25.2
This is the result of my script:
No. 1 : IP = 172.25.25.1
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
: Name or service not known: ssh: Could not resolve hostname 172.25.25.1
FAILED
########################################
No. 2 : IP = 172.25.25.2
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
: Name or service not known: ssh: Could not resolve hostname 172.25.25.2
FAILED
########################################

check the file endings, if they are CRLF for windows, CR for mac, or LF for linux.
while read -r line; do COMMAND; done
The -r option passed to read command prevents backslash escapes from being interpreted.
Add IFS= option before read command to prevent leading/trailing whitespace from being trimmed -
while IFS= read -r line; do COMMAND_on $line; done
the code above is an example, you may want to use the -r parameter. For IFS you probably do not want to use this, because if there was any whitespace, then IFS would keep this and not remove them.

Related

Capturing SSH Output in a variable in a bash script

I'm trying to SSH into another machine and caputre it's ip address and hostname into a variable.
However, the varaible seems to be empty when i echo it.
I have tried out answers from other posts, but it didnt solve my problem. I'm not able to figure out as what the problem is.
#!/bin/bash
FILE=/home/admin/Vishal/output.txt
input=host.txt
while IFS= read -r line
do
echo "$line"
if [ $line = $HOSTNAME ]
then
ip=`hostname -i`
domain=`hostname -A`
host=`hostname`
sudo echo $ip $domain $line localhost >> $FILE
else
output=$(ssh -i -t admin#$line << "ENDSSH"
ip2=`hostname -i`
domain2=`hostname -A`
host2=`hostname`
ENDSSH
)
echo $output
fi
done <"$input"
The input file contains a list of hostnames
The variable FILE contains the path of the file where the results are to be stored.
The varaible output is the one in which i want to store the results.
Note: The script works for first part of the if where ssh isnt required.
Ony this command is relevant for your quesion:
output=$(ssh -i -t admin#$line << "ENDSSH"
ip2=`hostname -i`
domain2=`hostname -A`
host2=`hostname`
ENDSSH
)
The command sets some variables, but doesn't produce any output, so it's expected that output does't contain your values.
If you really want three lines with hostname related values, then something simple like this should work
output=$(ssh admin#$line "hostname -i; hostname -A; hostname")

Linux script throwing error though it completely looks fine

I have to write Linux script for below question
Write a script that renames files based on the file extension.  The script should prompt the user  for a file extension.  
Next, it should ask the user what prefix to prepend to the file name(s).  By  default the prefix should be the current date in YYYY­MM­DD format.  
So, if the user simply  presses enter the date will be used.  Otherwise, whatever the user entered will be used as the  prefix.  
Next, it should display the original file name and the new name of the file.  Finally, it  should rename the file. 
I wrote below shell script & its throwing error. To me script looks completely fine. Though I am able to write alternative script but Could someone please suggest reason & resolution of error in this script.
Script:
#!/bin/bash
read -p "Please enter a file extension : " EXT
for f in *.${EXT}
do
read -p "Please enter a file prefix (Press ENTER to prefix current Date) :" PREFIX
if [ -z "PREFIX" ]
then
new = "$(date +"%Y-%M-%d")-$(basename ${f})"
mv $f $new
echo "$f renamed to $new"
else
new = "${PREFIX}-${f}"
mv $f $new
echo "$f renamed to $new"
fi
done
Error :
./new.sh: line 13: new: command not found
BusyBox v1.24.2 (2017-05-25 17:33:59 CEST) multi-call binary.
Usage: mv [-fin] SOURCE DEST
or: mv [-fin] SOURCE... DIRECTORY
Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY
-f Don't prompt before overwriting
-i Interactive, prompt before overwrite
-n Don't overwrite an existing file
*.png renamed to
[root#localhost ~]#
[root#localhost ~]#
The spaces are spoiling your script during assignment
#new = "$(date +"%Y-%M-%d")-$(basename ${f})"
new="$(date +"%Y-%M-%d")-$(basename ${f})"
also
#new = "${PREFIX}-${f}"
new="${PREFIX}-${f}"
shellcheck is an excellent tool for a basic shell checking

Bash read -p doesnt work [duplicate]

This question already has answers here:
': not a valid identifier [duplicate]
(4 answers)
Why would a correct shell script give a wrapped/truncated/corrupted error message? [duplicate]
(1 answer)
Closed 5 years ago.
When running my shell script I get this error:
': not a valid identifiere 17: read: `
Here is my shell script:
#!/usr/bin/env bash
# Mr. Robot Install Wordpress Script
# Script is used for the following:
# add user to server
# change to new user home directory
# download latest version of wordpress
# unzip wordpress
# move all files up a directory level
# move up a directory level
# delete wordpress.zip
# remove wordpress folder
echo "/*****************************************************/"
echo "/************** HELLO MR. ROBOT **********************/"
echo "/*****************************************************/"
echo ".."
echo ".."
echo "Website URL"
echo 'url: \r'
read -p $website
echo 'User: \r'
read -p $newuser
echo 'Pass: \r'
read -p $password
echo "creating account......"
/scripts/wwwacct $website $newuser $password 0 x3 n n n 0 0 0 0 0 0
echo "Changing Directory....."
cd ~/home/$newuser/
echo "Getting Latest Version of Wordpress!"
curl -O http://wordpress.org/latest.tar.gz
echo "Tarball Incoming!!"
tar xvzf latest.tar.gz
echo "removing tar file"
rm latest.tar.gz
echo "moving wordpress folders!"
cp -a ~/home/$newuser/public_html/wordpress/. ~/home/$newuser/public_html/
cd /home/$newuser/public_html/
echo "Part 01 Complete!!"
exit
I've tried to use different versions of the read line with -p or -e. Any help would be appreciated. I've even tried adding it on a separate line with input.
EDIT: Updated file to where it takes inputs, but issue is that the inputs are not being used through the rest of the script. Thus causing errors for directories not being found.
Don't quote the variables names. read needs the name of the variable to assign to, not its value, which is what you get if you have a dollar sign $.
read -p 'website url: ' website
read -p 'Username: ' newuser
read -p 'Password: ' password
It looks like one of the variables holds \r, a carriage return. The error message that bash is trying to print is something like:
bash: ./script: line 17: read: `\r': not a valid identifier
But \r causes the cursor to go back to the beginning of the line, causing ': not a valid identifier to overwrite the beginning of the message.
As mentioned above by John Kugelman, in case you have to check if you Input_file is having carriage returns then you could run following command:
cat -v Input_file
In case you find them then try to remove them from either of following cmmands:
tr -d '\r' < Input_file
OR
awk '{gsub(/\r/,"")} 1' Input_file
Or check if your system(box) has dos2unix utility you could use that also for removing these carriage returns.

Bash script does not ssh all the entries of a csv file

I am trying to patch a bunch of CENT OS machines with the latest fix pack. I have the below bash script that takes csv file as a input which has the ip address and password for those machines.
The code works fine however, it would only work for the first row it does not seem to be working for the rest of the list as my output.txt only has the entry only for the first row host .
patch.sh
INPUT=hosts_test.cvs
OLDIFS=$IFS
IFS=,
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read privateip password
do
sshpass -p$password ssh -t -o "StrictHostKeyChecking no" user123#$privateip "
hostname
hostname -I --all-ip-addresses
sudo yum -y update bash
env x='() { :;}; echo vulnerable' bash -c \"echo If you see the word vulnerable above, then you are vulnerable to shellshock\"
echo ""
exit
" >> output.txt
done < $INPUT
IFS=$OLDIFS
hosts_test.cvs
10.xxx.xx.219,abcd~qY1
10.xxx.xx.226,l4~abcdefg
10.xxx.xx.221,l4#abcdefgh
Terminal Output
Pseudo-terminal will not be allocated because stdin is not a terminal.
Add at the end of your sshpass command </dev/null.
Add Defaults:username !requiretty to your /etc/sudoers config
Get rid of -t from your ssh command
Optional, but recommended: set up public key auth so you don't have your passwords lying around in text files.
You can pass ssh another -t to force pty allocation:
ssh -t -t

Splitting string into array upon token

I'm writing a script to perform an offsite rsync backup, and whenever the rsyncline recieves some output it goes into a single variable. I then want to split that variable into an array upon the ^M token, so that I can send them to two different logger-sessions (so I get them on seperate lines in the log).
My current line to perform the rsync
result=`rsync --del -az -e "ssh -i $cert" $source $destination 2>&1`
Result in the log, when the server is unavailable
ssh: connect to host offsite port 22: Connection timed out^M rsync: connection unexpectedly closed (0 bytes received so far) [sender] rsync error: unexplained error (code 255) at io.c(601) [sender=3.0.7]
IFS=$'\n' read -a foo <<< $'12\n345\n67'
echo "${foo[#]}"
^M is $'\r' so you might try that as your delimiter:
IFS=$'\r' read -ar result <<< $(rsync --del -az -e "ssh -i $cert" $source $destination 2>&1)
echo ${result[0]} # first part
echo ${result[1]} # second part
IFS=$'\r'
set -- $result
echo $1
echo $2
Thanks guys, trough a mix of your answers, I came up with a working solution. Here it is.
result=`rsync --del -az -e "ssh -i $cert" $source $destination 2>&1`
IFS=$'\n'
for variable in $result; do
logger $variable
done
unset IFS
Now the entire script works!

Resources