bash script to execute a command remote servers using ssh

Hello,

I am running into few issues, please suggest me what I am missing.

I am running this script on a linux host.

Main idea of this script is to, login to each host via ssh and get uid of user, service user that I trying to run this script, has already deployed ssh keys and provide sudo access to root with password less on all the server.

issue: /tmp/hostname.txt file contains list of IP addresses line by line, when I execute this script, I get the o/p of the first host successfully and stops executing right from that point.

# more userid
#!/bin/bash
while read line
do
        ssh $line '(echo "`hostname` UID for User v7866 is `getent passwd v7866 | cut -f3 -d:`")' >> /tmp/output
done < /tmp/hostname.txt
#
#more /tmp/hostname.txt
10.10.7.182
10.10.7.173
10.10.7.143
#

Thanks,

ssh tries to read from the same standard input as your while loop, 'eating' your entire datafile.

Also, you don't need to re-open the same logfile 9,000 times to write 9,000 lines.

Also, the braces aren't necessary.

#!/bin/bash
while read line
do
        ssh $line 'echo "`hostname` UID for User v7866 is `getent passwd v7866 | cut -f3 -d:`"' </dev/null
done < /tmp/hostname.txt > /tmp/output

A better way to accomplish this is to invoke the script which contains the commands that you want to be executed at the remote server

for ip_addr in $(cat hostname.txt); do
     ssh ${ip_addr} "bash -s" < script_to_be_invoked
done

As you'll see that, this way

ssh ip_addr "commands"

won't work properly while the "commands" is getting longer!
Look at this http://www.unix.com/shell-programming-scripting/180335-executing-local-script-command-remote-server.html
The reason why your commands will only be run on the first host connected to is detailed explained here
http://72.14.189.113/howto/shell/while-ssh/

1 Like

Thanks for the help,

I was able to run the script as suggested works fine !!!!

for ip_addr in $(cat hostname.txt); do
     ssh ${ip_addr} "bash -s" < script_to_be_invoked
done

The only annoying part is, once the user ssh into the each server, I see banner is being displayed on the terminal, how do we remove that from the output.

Thanks,

Just map the ip addresses of your remote servers' with a unique name one by one and line by line in your /etc/hosts on the master server which can manage all your remote servers

192.168.0.17 node0
192.168.0.18 node1
192.168.0.19 node2

A more convenient way to perform your tasks with ssh at the remote servers is to invoke another script ssh.sh

ssh ${0##*/} "${@}"

just locate the script ssh.sh in /usr/local/sbin, then make some soft links:

# cd /usr/local/sbin
# ln -s ssh.sh node0
# ln -s ssh.sh node1
# ln -s ssh.sh node2

after you have done this, you can login to remote server,say, login to node1, you can just execute

# node1

instead of

# ssh node1

or

# ssh 192.168.0.18

and the same way to execute your commands

# node1 "commands"

instead of

# ssh node1 "commands"

and so

for node in node1 node2 node3; do
     ${node} "bash -s" < script_to_be_invoked
done

The script below is detailed explained what you can do with no-ssh needed remote commands execution

#!/bin/bash
#
# ssh.sh
# node1 "echo '${local_variable}'"
# node1 "cat local_big_archive.tar.bz2" | tar -jxpvf -
# tar -jcpvf - /path/to/data | node1 "cat > /dev/tape"
# node1 "cd /path/to/dir; tar -jxpvf -" < local_big_archive.tar.bz2
# node1 "dd if=/dev/sda bs=512 count=1" | node2 "cd /usr; dd of=mbr.bin"
# node1 "dd <  /dev/sda bs=512 count=1" | node2 "cd /usr; dd >  mbr.bin"
# node1 "mysqldump" | mysql
# node1 "mysqldump" > backup.sql
# node1 
# node1 "uptime"
# node1 "uptime" > local_file  
# node1 "uptime  > remote_file"
# node1 "bash -s" < script_to_run
# node1 "bash -s" < script_to_run > local_file
# node1 "bash -s  > remote_file" < script_to_run
# tar -jcpvf - /path/to/data | node1 "cd /target/dir; tar -jxpvf -"
# cd /target/dir; node1 "tar -jcpvf - /path/to/data" |  tar -jxpvf -
# rsync -Pvzrtopg /path/to/data/ node1:/root/
# rsync -Pvzrtopg node1:/path/to/data /root/

ssh ${0##*/} "${@}"

When I tried to include sudo command in the place script to be executed I am getting this error messages, any idea how can I overcome !!!!

#!/bin/bash
for ip_addr in $(cat ipaddress.txt); do
ssh -t ${ip_addr} "bash -s" < /uploadscript.txt
done
#
#more /uploadscript.txt
sudo echo xy12ls1 | passwd --stdin martin

when I run this script I am getting this error message

$ ./remotescript
Pseudo-terminal will not be allocated because stdin is not a terminal.

Thanks,

Try

-t -t

to force it to allocate a tty even though there's no local tty.

can someone please suggest, I am trying to update user password on remote server. user who is trying to run this script have sudo rules setup with password less. I am not sure where I am missing here.

$ ssh -t 10.10.10.89 "bash -s" < 'sudo echo Welcome | passwd --stdin neen'
-bash: sudo echo Welcome | passwd --stdin neen: No such file or directory
$ ssh -t 10.10.10.89 "bash -s" < sudo echo Welcome | passwd --stdin neen
-bash: sudo: No such file or directory
Only root can do that.
$

Thanks,

< doesn't work that way. Try a here-document.

ssh -t 10.10.10.89 <<EOF
        echo "password" | sudo passwd --stdin username
EOF

It's entirely possible sudo isn't configured to allow you to do that, and/or passwd can't take passwords from stdin.