write a shell script to ssh to a remote machine and execute commands

LinuxShellSsh

Linux Problem Overview


I have two questions:

  1. There are multiple remote linux machines, and I need to write a shell script which will execute the same set of commands in each machine. (Including some sudo operations). How can this be done using shell scripting?
  2. When ssh'ing to the remote machine, how to handle when it prompts for RSA fingerprint authentication.

The remote machines are VMs created on the run and I just have their IPs. So, I cant place a script file beforehand in those machines and execute them from my machine.

Linux Solutions


Solution 1 - Linux

> There are multiple remote linux machines, and I need to write a shell script which will execute the same set of commands in each machine. (Including some sudo operations). How can this be done using shell scripting?

You can do this with ssh, for example:

#!/bin/bash
USERNAME=someUser
HOSTS="host1 host2 host3"
SCRIPT="pwd; ls"
for HOSTNAME in ${HOSTS} ; do
    ssh -l ${USERNAME} ${HOSTNAME} "${SCRIPT}"
done

> When ssh'ing to the remote machine, how to handle when it prompts for RSA fingerprint authentication.

You can add the StrictHostKeyChecking=no option to ssh:

ssh -o StrictHostKeyChecking=no -l username hostname "pwd; ls"

This will disable the host key check and automatically add the host key to the list of known hosts. If you do not want to have the host added to the known hosts file, add the option -o UserKnownHostsFile=/dev/null.

Note that this disables certain security checks, for example protection against man-in-the-middle attack. It should therefore not be applied in a security sensitive environment.

Solution 2 - Linux

Install sshpass using, apt-get install sshpass then edit the script and put your linux machines IPs, usernames and password in respective order. After that run that script. Thats it ! This script will install VLC in all systems.

#!/bin/bash
SCRIPT="cd Desktop; pwd;  echo -e 'PASSWORD' | sudo -S apt-get install vlc"
HOSTS=("192.168.1.121" "192.168.1.122" "192.168.1.123")
USERNAMES=("username1" "username2" "username3")
PASSWORDS=("password1" "password2" "password3")
for i in ${!HOSTS[*]} ; do
     echo ${HOSTS[i]}
     SCR=${SCRIPT/PASSWORD/${PASSWORDS[i]}}
     sshpass -p ${PASSWORDS[i]} ssh -l ${USERNAMES[i]} ${HOSTS[i]} "${SCR}"
done

Solution 3 - Linux

This work for me.

Syntax : ssh -i pemfile.pem user_name@ip_address 'command_1 ; command 2; command 3'

#! /bin/bash

echo "########### connecting to server and run commands in sequence ###########"
ssh -i ~/.ssh/ec2_instance.pem ubuntu@ip_address 'touch a.txt; touch b.txt; sudo systemctl status tomcat.service'

Solution 4 - Linux

There are a number of ways to handle this.

My favorite way is to install http://pamsshagentauth.sourceforge.net/ on the remote systems and also your own public key. (Figure out a way to get these installed on the VM, somehow you got an entire Unix system installed, what's a couple more files?)

With your ssh agent forwarded, you can now log in to every system without a password.

And even better, that pam module will authenticate for sudo with your ssh key pair so you can run with root (or any other user's) rights as needed.

You don't need to worry about the host key interaction. If the input is not a terminal then ssh will just limit your ability to forward agents and authenticate with passwords.

You should also look into packages like Capistrano. Definitely look around that site; it has an introduction to remote scripting.

Individual script lines might look something like this:

ssh remote-system-name command arguments ... # so, for exmaple,
ssh target.mycorp.net sudo puppet apply

Solution 5 - Linux

If you are able to write Perl code, then you should consider using Net::OpenSSH::Parallel.

You would be able to describe the actions that have to be run in every host in a declarative manner and the module will take care of all the scary details. Running commands through sudo is also supported.

Solution 6 - Linux

For this kind of tasks, I repeatedly use Ansible which allows to duplicate coherently bash scripts in several containets or VM. Ansible (more precisely Red Hat) now has an additional web interface AWX which is the open-source edition of their commercial Tower.

Ansible: https://www.ansible.com/
AWX:https://github.com/ansible/awx
Ansible Tower: commercial product, you will probably fist explore the free open-source AWX, rather than the 15days free-trail of Tower

Solution 7 - Linux

There is are multiple ways to execute the commands or script in the multiple remote Linux machines. One simple & easiest way is via pssh (parallel ssh program)

pssh: is a program for executing ssh in parallel on a number of hosts. It provides features such as sending input to all of the processes, passing a password to ssh, saving the output to files, and timing out.

Example & Usage:

Connect to host1 and host2, and print "hello, world" from each:

 pssh -i -H "host1 host2" echo "hello, world"

Run commands via a script on multiple servers:

pssh -h hosts.txt -P -I<./commands.sh

Usage & run a command without checking or saving host keys:

pssh -h hostname_ip.txt -x '-q -o StrictHostKeyChecking=no -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes' -i  'uptime; hostname -f'

If the file hosts.txt has a large number of entries, say 100, then the parallelism option may also be set to 100 to ensure that the commands are run concurrently:

pssh -i -h hosts.txt -p 100 -t 0 sleep 10000

Options:
-I: Read input and sends to each ssh process.
-P: Tells pssh to display output as it arrives.
-h: Reads the host's file.
-H : [user@]host[:port] for single-host.
-i: Display standard output and standard error as each host completes
-x args: Passes extra SSH command-line arguments
-o option: Can be used to give options in the format used in the configuration file.(/etc/ssh/ssh_config) (~/.ssh/config)
-p parallelism: Use the given number as the maximum number of concurrent connections
-q Quiet mode: Causes most warning and diagnostic messages to be suppressed.
-t: Make connections time out after the given number of seconds. 0 means pssh will not timeout any connections

> When ssh'ing to the remote machine, how to handle when it prompts for > RSA fingerprint authentication.

Disable the StrictHostKeyChecking to handle the RSA authentication prompt.
-o StrictHostKeyChecking=no

Source: man pssh

Solution 8 - Linux

This worked for me. I made a function. Put this in your shell script:

sshcmd(){
    ssh $1@$2 $3
}

sshcmd USER HOST COMMAND

If you have multiple machines that you want to do the same command on you would repeat that line with a semi colon. For example, if you have two machines you would do this:

sshcmd USER HOST COMMAND ; sshcmd USER HOST COMMAND

Replace USER with the user of the computer. Replace HOST with the name of the computer. Replace COMMAND with the command you want to do on the computer.

Hope this helps!

Solution 9 - Linux

The accepted answer sshes to machines sequentially. In case you want to ssh to multiple machines and run some long-running commands like scp concurrently on them, run the ssh command as a background process.

#!/bin/bash
username="user"
servers=("srv-001" "srv-002" "srv-002" "srv-003");
script="pwd;"
for s in "${servers[@]}"; do
    echo "sshing ${username}@${s} to run ${script}"
    (ssh ${username}@${s} ${script})& # Run in background
done
wait # If removed, you can run some other script here

Solution 10 - Linux

You can follow this approach :

  • Connect to remote machine using Expect Script. If your machine doesn't support expect you can download the same. Writing Expect script is very easy (google to get help on this)

  • Put all the action which needs to be performed on remote server in a shell script.

  • Invoke remote shell script from expect script once login is successful.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBalanivashView Question on Stackoverflow
Solution 1 - LinuxAndreas FesterView Answer on Stackoverflow
Solution 2 - LinuxArjun G PerambraView Answer on Stackoverflow
Solution 3 - LinuxViraj WadateView Answer on Stackoverflow
Solution 4 - LinuxDigitalRossView Answer on Stackoverflow
Solution 5 - LinuxsalvaView Answer on Stackoverflow
Solution 6 - LinuxFiboView Answer on Stackoverflow
Solution 7 - LinuxSkanda ShastryView Answer on Stackoverflow
Solution 8 - LinuxAnonymous ContributorView Answer on Stackoverflow
Solution 9 - LinuxhmofradView Answer on Stackoverflow
Solution 10 - Linuxrai.skumarView Answer on Stackoverflow