Execute Linux Commands on Remote System 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.

The general syntax is as follow:

$ ssh [User_Name]@[Rremote_Host_Name or IP] [Command or Script]

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.

1) How to Run the Command on a Remote Linux System Over SSH
The following example allows users to run the df command via ssh on a remote Linux machine

[root@node01 ~]# ssh admin@node02 df -h
admin@node02's password:
Filesystem Size Used Avail Use% Mounted on
devtmpfs 485M 0 485M 0% /dev
tmpfs 496M 0 496M 0% /dev/shm
tmpfs 496M 6.9M 489M 2% /run
tmpfs 496M 0 496M 0% /sys/fs/cgroup
/dev/mapper/centos-root 6.2G 3.3G 3.0G 53% /
/dev/sda1 1014M 162M 853M 16% /boot
tmpfs 100M 0 100M 0% /run/user/0
/dev/sr0 4.3G 4.3G 0 100% /mnt
tmpfs 100M 0 100M 0% /run/user/1024
[root@node01 ~]#


2) How to Run Multiple Commands on a Remote Linux System Over SSH
The following example allows users to run multiple commands at once over ssh on the remote Linux system. It’s running "uname -n" command and "free" command on the remote Linux system simultaneously.

[root@node01 ~]# ssh admin@node02 "uname -n && free -m"
admin@node02's password:
node02
total used free shared buff/cache available
Mem: 991 182 475 6 332 665
Swap: 819 0 819
[root@node01 ~]#


3) How to Run the Command with sudo Privilege on a Remote Linux System Over SSH
The following example allows users to run the fdisk command with sudo privilege on the remote Linux system via ssh. Normal users are not allowed to execute commands available under the system binary (/usr/sbin/) directory. Users need root privileges to run it. So to run the fdisk command on a Linux system, you need root privileges.

[root@node01 ~]# ssh -t admin@node02 "sudo fdisk -l"
admin@node02's password:
Disk /dev/sda: 8589 MB, 8589934592 bytes, 16777216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000a7db2
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 2099199 1048576 83 Linux
/dev/sda2 2099200 16777215 7339008 8e Linux LVM
Disk /dev/sdb: 8589 MB, 8589934592 bytes, 16777216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mapper/centos-root: 6652 MB, 6652166144 bytes, 12992512 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mapper/centos-swap: 859 MB, 859832320 bytes, 1679360 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Connection to node02 closed.
[root@node01 ~]#

4) How to Run the Service Command with sudo Privilege on a Remote Linux System Over SSH
The following example allows users to run the service command with sudo privilege on the remote Linux system via ssh.
[root@node01 ~]# date
Thu Apr 16 09:29:16 EDT 2020
[root@node01 ~]# ssh -t admin@node02 "sudo systemctl restart rsyslog"
admin@node02's password:
Connection to node02 closed.
[root@node01 ~]# ssh -t admin@node02 "sudo systemctl status rsyslog"
admin@node02's password:
● rsyslog.service - System Logging Service
Loaded: loaded (/usr/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2020-04-16 09:29:22 EDT; 4s ago
Docs: man:rsyslogd(8)
http://www.rsyslog.com/doc/
Main PID: 2386 (rsyslogd)
Tasks: 3
Memory: 904.0K
CGroup: /system.slice/rsyslog.service
└─2386 /usr/sbin/rsyslogd -n
Apr 16 09:29:22 node02 systemd[1]: Stopped System Logging Service.
Apr 16 09:29:22 node02 systemd[1]: Starting System Logging Service...
Apr 16 09:29:22 node02 rsyslogd[2386]: [origin software="rsyslogd" swVersion="8.24.0-41.el7_7.2" x-pid...start
Apr 16 09:29:22 node02 systemd[1]: Started System Logging Service.
Hint: Some lines were ellipsized, use -l to show in full.
Connection to node02 closed.
[root@node01 ~]#

5) How to Run the Command on a Remote Linux System Over SSH With Non-Standard Port
The following example allows users to run the hostnamectl command via ssh on a remote Linux machine with non-standard port.
[root@node01 ~]# ssh -p 22 admin@node02 hostnamectl
admin@node02's password:
Static hostname: node02
Icon name: computer-vm
Chassis: vm
Machine ID: 76328c635e1d44509a511525376b29df
Boot ID: 17c9db311f264f8d936014adbaab0b7b
Virtualization: kvm
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-1062.9.1.el7.x86_64
Architecture: x86-64
[root@node01 ~]#

6) How to Save Output from Remote System to Local System
The following example allows users to remotely execute the top command on a Linux system via ssh and save the output to the local system.
[root@node01 ~]# ssh admin@node02 "top -bc | head -n 35" > /tmp/top-output.txt
admin@node02's password:
[root@node01 ~]# head /tmp/top-output.txt
top - 09:32:26 up 2:20, 2 users, load average: 0.00, 0.02, 0.05
Tasks: 108 total, 1 running, 107 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 6.2 sy, 0.0 ni, 93.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1014808 total, 484216 free, 187612 used, 342980 buff/cache
KiB Swap: 839676 total, 839676 free, 0 used. 680924 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 125356 3892 2600 S 0.0 0.4 0:01.61 /usr/lib/sy+
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 [kthreadd]
4 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 [kworker/0:+
[root@node01 ~]#


Alternatively, you can use the following format to run multiple commands on a remote system

[root@node01 ~]# ssh admin@node02 << EOF
> uname -n
> free -m
> grep admin /etc/passwd
> EOF

Pseudo-terminal will not be allocated because stdin is not a terminal.
admin@node02's password:
node02
total used free shared buff/cache available
Mem: 991 182 473 6 334 665
Swap: 819 0 819
admin:x:1024:1024::/home/admin:/bin/bash
[root@node01 ~]#


7) How to Execute Local Bash Scripts on Remote System
The following example allows users to run local bash script “remote-test.sh” via ssh on a remote Linux machine.
Create a shell script and execute it.
[root@node01 ~]# vi /tmp/remote-test.sh
#!/bin/bash
#Name: remote-test.sh
#--------------------
uptime
free -m
df -h
uname -a
[root@node01 ~]#
Output for the above command.

[root@node01 ~]# ssh admin@node02 "bash -s" < /tmp/remote-test.sh
admin@node02's password:
09:36:52 up 2:24, 2 users, load average: 0.00, 0.01, 0.05
total used free shared buff/cache available
Mem: 991 182 473 6 335 665
Swap: 819 0 819
Filesystem Size Used Avail Use% Mounted on
devtmpfs 485M 0 485M 0% /dev
tmpfs 496M 0 496M 0% /dev/shm
tmpfs 496M 6.9M 489M 2% /run
tmpfs 496M 0 496M 0% /sys/fs/cgroup
/dev/mapper/centos-root 6.2G 3.3G 3.0G 53% /
/dev/sda1 1014M 162M 853M 16% /boot
tmpfs 100M 0 100M 0% /run/user/0
/dev/sr0 4.3G 4.3G 0 100% /mnt
tmpfs 100M 0 100M 0% /run/user/1024
Linux node02 3.10.0-1062.9.1.el7.x86_64 #1 SMP Fri Dec 6 15:49:49 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
[root@node01 ~]#


8) How to Run Multiple Commands on Multiple Remote Systems Simultaneously
The following bash script allows users to run multiple commands on multiple remote systems simultaneously. Use simple for loop to achieve it. For this purpose, you can try with with the PSSH command or ClusterShell command or DSH command
[root@node01 ~]# cat /tmp/multiple-host.sh
for host in node01 node02
do
ssh admin@${host} "uname -a;uptime;date;w"
done
[root@node01 ~]# sh /tmp/multiple-host.sh

admin@node01's password:
Linux node01 3.10.0-1062.9.1.el7.x86_64 #1 SMP Fri Dec 6 15:49:49 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
09:43:05 up 2:31, 4 users, load average: 0.08, 0.03, 0.05
Thu Apr 16 09:43:05 EDT 2020
09:43:05 up 2:31, 4 users, load average: 0.08, 0.03, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root tty1 07:11 2:29m 0.01s 0.01s -bash
root pts/0 192.168.2.54 07:17 1:20m 0.13s 0.13s -bash
root pts/1 192.168.2.54 08:18 1:22m 0.07s 0.04s ssh d01
root pts/2 192.168.2.54 09:21 1.00s 0.16s 0.01s ssh admin@node01 uname -a;uptime;date;w
admin@node02's password:
Linux node02 3.10.0-1062.9.1.el7.x86_64 #1 SMP Fri Dec 6 15:49:49 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
09:43:06 up 2:30, 2 users, load average: 0.00, 0.01, 0.05
Thu Apr 16 09:43:06 EDT 2020
09:43:06 up 2:30, 2 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root tty1 07:12 2:30m 0.00s 0.00s -bash
root pts/0 p01.example.com 08:19 1:22m 0.01s 0.01s -bash
[root@node01 ~]#


9) How to Add a Password Using the sshpass Command
If you are having trouble entering your password each time, I advise you to go with any one of the methods below as per your requirement. If you are going to perform this type of activity frequently, I advise you to set up password-less authentication since it’s a standard and permanent solution.
If you only do these tasks a few times a month. I recommend you to use the “sshpass” utility.
Just provide a password as an argument using the “-p” option.
[root@node01 ~]# sshpass -p 'redhat' ssh admin@node02 "uname -n; uptime"
node02
09:47:47 up 2:35, 2 users, load average: 0.00, 0.01, 0.05
[root@node01 ~]#

Install  sshpass Package 
Download latest rpmforge-release rpm from
http://ftp.tu-chemnitz.de/pub/linux/dag/redhat/el7/en/x86_64/rpmforge/RPMS/
Install rpmforge-release rpm:
[root@node01 ~]#  rpm -Uvh rpmforge-release*rpm
Install sshpass rpm package:
[root@node01 ~]#  yum install sshpass

10) How to use Variable expansion
If we split commands into multiple lines, then variable expansion will not work. Let us see it with simple example:
[root@node01 ~]# msg="Hello All"
[root@node01 ~]# ssh admin@node02 'echo $msg'
admin@node02's password:

[root@node01 ~]#

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:
[root@node01 ~]# msg="Hello friend"
[root@node01 ~]# ssh admin@node02 bash -c "'echo $msg'"

admin@node02's password:
Hello friend
[root@node01 ~]#

11 ) How to 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:
A) Generate public-private key pairSSH provides ssh-keygen utility which can be used to generate key pairs on local machine.

[root@node01 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:E3bjZHIV7hoNz+TCHGp++TV9U7VzXsgikrPTty/6cAg root@node01

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

B) Add public key to ~/.ssh/authorized_keys file on remote host
Simple way to do this is, using ssh-copy-id command.
[root@node01 ~]# ssh-copy-id admin@node02
admin@node02's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'admin@node02'"
and check to make sure that only the key(s) you wanted were added.
[root@node01 ~]#

[root@node01 ~]# ssh admin@node02
Last login: Thu Apr 16 09:29:27 2020 from p01.example.com
[admin@node02 ~]$


12 )  Login to server as root and su to admin and execute the script. 

[root@node01 ~]# ssh admin@node02 "cat /home/admin/script/uptime.sh"
uptime >> /tmp/uptime
[root@node01 ~]# ssh admin@node02 "cat /tmp/admin.sh"
su - admin -c "cd /home/admin/script/ && sh uptime.sh "
[root@node01 ~]# ssh node02 /tmp/admin.sh
root@node02's password:
[root@node01 ~]# ssh node02 "cat /tmp/uptime"
root@node02's password:
10:31:27 up 3:19, 3 users, load average: 0.00, 0.01, 0.05
10:31:31 up 3:19, 3 users, load average: 0.00, 0.01, 0.05
10:32:19 up 3:19, 1 user, load average: 0.00, 0.01, 0.05
10:34:04 up 3:21, 1 user, load average: 0.00, 0.01, 0.05
10:35:57 up 3:23, 1 user, load average: 0.00, 0.01, 0.05
[root@node01 ~]#

No comments:

Post a Comment