How to Execute Linux Commands on Remote System over SSH

Run-Linux-Commands-Remote-systems-Over-SSH

Overview

Many times we need to work with remote Linux systems. We login to the remote host, perform work and exit that session. Can we perform all these actions from local machine ? Yes, it’s possible and this tutorial demonstrates it with exhaustive examples.

Command execution over SSH

SSH allows us to execute command on remote machine without logging into that machine. In this tutorial we’ll discuss various ways to achieve this.

Execute single command

Let us execute uname command over SSH.

$ ssh [email protected] uname

If you observe above command, it is similar to regular SSH command with minor difference. We have appended command to be executed (highlighted in red color).

When we execute this command. It’ll generate below output:

Linux
Execute multiple commands

Using this technique, we can execute multiple commands using single SSH session. We just need to separate commands with semicolon (;).

$ ssh [email protected] "uname;hostname;date"

As expected, these commands will generate below output:

Linux
linux-server
Thu Mar  1 15:47:59 IST 2018
Execute command with elevated privileges

Sometimes we need to execute command with elevated privileges, in that case we can use it with sudo.

$ ssh -t [email protected] sudo touch /etc/banner.txt

Note that we have used ‘-t‘ option with SSH, which allows pseudo-terminal allocation. sudo command requires interactive terminal hence this option is necessary.

Execute script

Remote execution is not only limited to the commands; we can even execute script over SSH. We just have to provide absolute path of local script to SSH command.

Let us create a simple shell script with following contents and name it as system-info.sh

#!/bin/sh
uname
hostname

Make script executable and run it on remote server as follows:

$ chmod +x system-info.sh
$ ssh [email protected] ./system-info.sh

As some of you might have guessed, it will generate below output:

Linux
linux-server
Variable expansion problem

If we split commands into multiple lines, then variable expansion will not work. Let us see it with simple example:

$ msg="Hello LinuxTechi"
$ ssh [email protected] 'echo $msg'

When we execute above command, we can observe that variable is not getting expanded.

To resolve this issue, we need to use -c option of shell. In our case we’ll use it with bash as follows:

$ ssh [email protected] bash -c "'echo $msg'"
Configure password-less SSH session

By default, SSH will ask for password authentication each time. This is enforced for security reasons. However, sometimes it is annoying. To overcome this, we can use public-private key authentication mechanism.

It can be configured using following steps:

1) Generate public-private key pair

SSH provides ssh-keygen utility which can be used to generate key pairs on local machine.

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/linuxtechi/.ssh/id_rsa): #press enter
Enter passphrase (empty for no passphrase):                         #press enter
Enter same passphrase again:                                        #press enter
Your identification has been saved in /home/linuxtechi/.ssh/id_rsa.
Your public key has been saved in /home/linuxtechi/.ssh/id_rsa.pub.

Above output shows that generated key pairs are stored under ~/.ssh directory.

2)  Add public key to ~/.ssh/authorized_keys file on remote host

Simple way to do this is, using ssh-copy-id command.

$ ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]

In above command:

  • -i option indicates identity file
  • ~/.ssh/id_rsa.pub is identity file
  • remaining text is remote user and remote server IP

NOTE: Never share your private key with anyone.

3) That’s it. Isn’t it so simple? Now we can execute command over SSH without entering password. Let us verify this.

$ ssh [email protected] uname

Limitation of public-private key authentication

Thought public-private key authentication makes our life easier, it is not perfect. Its major downside is; we cannot automate it, because user interaction is required first time. Remember !!! we have provided password to ssh-copy-id command.

There is no need to get panic, this is not end of world. In next section we’ll discuss approach which eliminates this limitation.

sshpass utility

To overcome above limitation, we can use sshpass utility. It provides non-interactive way to authenticate SSH session. This section discusses various ways of it.

Installation of sshpass

sshpass utility is part of Ubuntu’s official repository. We can install it using following commands:

$ sudo apt-get update
$ sudo apt-get install sshpass

Examples

sshpass can accept password – as an argument, read it from file or via environment variable. Let us discuss all these approaches.

1) Password as an argument

We can provide, password as an argument using –p option:

$ sshpass -p 'secrete-password' ssh [email protected] uname

2) Password from file

sshpass can read password from regular file using -f option:

$ echo "secrete-password" > password-file
$ sshpass -f password-file ssh [email protected] uname

3) Password from environment variable

In addition to this, we can provide password from environment variable using -e option:

$ export SSHPASS="secrete-password"
$ sshpass -e ssh [email protected] uname

Conclusion

This tutorial shows various tricks and tips on remote command execution over SSH. Once you get the understanding of these tricks it will make your life much easier and definitely improve your productivity.

6 Responses

  1. NILESHKUMAR CHHALLANI says:

    Awesome share

  2. yazul says:

    3rd example is wrong :
    $ ssh [email protected] uname; hostname; date

    commands “hostname” and “date” excute locally and not thru ssh tunnel !!!
    (local sh split command line on “;” and execute each of them.

    you can test :
    $ ssh [email protected] uname; uname
    $ ssh [email protected] hostame; hostame

    a correct example would be :
    $ ssh [email protected] “uname; hostname; date”

  3. ericm says:

    Hi Pradeep,

    the quote below seems to imply system-info.sh is a local script, which is executed on a remote system (192.168.10.10) However, I have found that this only work if the script is on the remote system. In other words, ssh can execute a script that is on the remote server. Is this also your experience or else can you clarify?

    We just have to provide absolute path of local script to SSH command.
    $ ssh [email protected] ./system-info.sh

  4. Fuseteam says:

    uh ssh-pass looks like a bad idea, or perhaps an incorrect usage?
    the way you presented it the actual password or the name of the password file or the name of the env variable will be logged in the command history !!!
    ssh via private and public key is way more secure as long as you keep your privatekey……..private

  5. Ken says:

    it looks like sshpass still will NOT work the first time when the local hostname has not been saved to the Known_hosts file in the remote host under .ssh directory. Does anyone know how to get along that?

Leave a Reply

Your email address will not be published. Required fields are marked *

Pin It on Pinterest