32

技术|如何通过 SSH 在远程 Linux 系统上运行命令

 4 years ago
source link: https://linux.cn/article-11440-1.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

我们有时可能需要在远程机器上运行一些命令。如果只是偶尔进行的操作,要实现这个目的,可以登录到远程系统上直接执行命令。但是每次都这么做的话,就有点烦人了。既然如此,有没有摆脱这种麻烦操作的更佳方案?

是的,你可以从你本地系统上执行这些操作,而不用登录到远程系统上。这有什么好处吗?毫无疑问。这会为你节省很多好时光。

这是怎么实现的?SSH 允许你无需登录到远程计算机就可以在它上面运行命令。

通用语法如下所示:



  1. $ ssh [用户名]@[远程主机名或 IP] [命令或脚本]

1) 如何通过 SSH 在远程 Linux 系统上运行命令

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行 df 命令



  1. $ ssh [email protected] df -h
  2. Filesystem Size Used Avail Use% Mounted on
  3. /dev/mapper/centos-root 27G 4.4G 23G 17% /
  4. devtmpfs 903M 0 903M 0% /dev
  5. tmpfs 920M 0 920M 0% /dev/shm
  6. tmpfs 920M 9.3M 910M 2% /run
  7. tmpfs 920M 0 920M 0% /sys/fs/cgroup
  8. /dev/sda1 1014M 179M 836M 18% /boot
  9. tmpfs 184M 8.0K 184M 1% /run/user/42
  10. tmpfs 184M 0 184M 0% /run/user/1000

2) 如何通过 SSH 在远程 Linux 系统上运行多条命令

下面的例子允许用户通过 ssh 在远程 Linux 机器上一次运行多条命令。

同时在远程 Linux 系统上运行 uptime 命令和 free 命令。



  1. $ ssh [email protected] "uptime && free -m"
  2. 23:05:10 up 10 min, 0 users, load average: 0.00, 0.03, 0.03
  3. total used free shared buffers cached
  4. Mem: 1878 432 1445 1 100 134
  5. -/+ buffers/cache: 197 1680
  6. Swap: 3071 0 3071

3) 如何通过 SSH 在远程 Linux 系统上运行带 sudo 权限的命令

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行带有 sudo 权限fdisk 命令。

普通用户不允许执行系统二进制(/usr/sbin/)目录下提供的命令。用户需要 root 权限来运行它。

所以你需要 root 权限,好在 Linux 系统上运行 fdisk 命令which 命令返回给定命令的完整可执行路径。



  1. $ which fdisk
  2. /usr/sbin/fdisk


  1. $ ssh -t [email protected] "sudo fdisk -l"
  2. [sudo] password for daygeek:
  3. Disk /dev/sda: 32.2 GB, 32212254720 bytes, 62914560 sectors
  4. Units = sectors of 1 * 512 = 512 bytes
  5. Sector size (logical/physical): 512 bytes / 512 bytes
  6. I/O size (minimum/optimal): 512 bytes / 512 bytes
  7. Disk label type: dos
  8. Disk identifier: 0x000bf685
  9. Device Boot Start End Blocks Id System
  10. /dev/sda1 * 2048 2099199 1048576 83 Linux
  11. /dev/sda2 2099200 62914559 30407680 8e Linux LVM
  12. Disk /dev/sdb: 10.7 GB, 10737418240 bytes, 20971520 sectors
  13. Units = sectors of 1 * 512 = 512 bytes
  14. Sector size (logical/physical): 512 bytes / 512 bytes
  15. I/O size (minimum/optimal): 512 bytes / 512 bytes
  16. Disk /dev/mapper/centos-root: 29.0 GB, 28982640640 bytes, 56606720 sectors
  17. Units = sectors of 1 * 512 = 512 bytes
  18. Sector size (logical/physical): 512 bytes / 512 bytes
  19. I/O size (minimum/optimal): 512 bytes / 512 bytes
  20. Disk /dev/mapper/centos-swap: 2147 MB, 2147483648 bytes, 4194304 sectors
  21. Units = sectors of 1 * 512 = 512 bytes
  22. Sector size (logical/physical): 512 bytes / 512 bytes
  23. I/O size (minimum/optimal): 512 bytes / 512 bytes
  24. Connection to centos7.2daygeek.com closed.

4) 如何通过 SSH 在远程 Linux 系统上运行带 sudo 权限的服务控制命令

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行带有 sudo 权限的服务控制命令。



  1. $ ssh -t [email protected] "sudo systemctl restart httpd"
  2. [sudo] password for daygeek:
  3. Connection to centos7.2daygeek.com closed.

5) 如何通过非标准端口 SSH 在远程 Linux 系统上运行命令

下面的例子允许用户通过 ssh 在使用了非标准端口的远程 Linux 机器上运行 hostnamectl 命令



  1. $ ssh -p 2200 [email protected] hostnamectl
  2. Static hostname: Ubuntu18.2daygeek.com
  3. Icon name: computer-vm
  4. Chassis: vm
  5. Machine ID: 27f6c2febda84dc881f28fd145077187
  6. Boot ID: bbeccdf932be41ddb5deae9e5f15183d
  7. Virtualization: oracle
  8. Operating System: Ubuntu 18.04.2 LTS
  9. Kernel: Linux 4.15.0-60-generic
  10. Architecture: x86-64

6) 如何将远程系统的输出保存到本地系统

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行 top 命令,并将输出保存到本地系统。



  1. $ ssh [email protected] "top -bc | head -n 35" > /tmp/top-output.txt


  1. cat /tmp/top-output.txt
  2. top - 01:13:11 up 18 min, 1 user, load average: 0.01, 0.05, 0.10
  3. Tasks: 168 total, 1 running, 167 sleeping, 0 stopped, 0 zombie
  4. %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
  5. KiB Mem : 1882300 total, 1176324 free, 342392 used, 363584 buff/cache
  6. KiB Swap: 2097148 total, 2097148 free, 0 used. 1348140 avail Mem
  7. PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
  8. 4943 daygeek 20 0 162052 2248 1612 R 10.0 0.1 0:00.07 top -bc
  9. 1 root 20 0 128276 6936 4204 S 0.0 0.4 0:03.08 /usr/lib/sy+
  10. 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 [kthreadd]
  11. 3 root 20 0 0 0 0 S 0.0 0.0 0:00.25 [ksoftirqd/+
  12. 4 root 20 0 0 0 0 S 0.0 0.0 0:00.00 [kworker/0:+
  13. 5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 [kworker/0:+
  14. 7 root rt 0 0 0 0 S 0.0 0.0 0:00.00 [migration/+
  15. 8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 [rcu_bh]
  16. 9 root 20 0 0 0 0 S 0.0 0.0 0:00.77 [rcu_sched]
  17. 10 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 [lru-add-dr+
  18. 11 root rt 0 0 0 0 S 0.0 0.0 0:00.01 [watchdog/0]
  19. 13 root 20 0 0 0 0 S 0.0 0.0 0:00.00 [kdevtmpfs]
  20. 14 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 [netns]
  21. 15 root 20 0 0 0 0 S 0.0 0.0 0:00.00 [khungtaskd]
  22. 16 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 [writeback]
  23. 17 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 [kintegrity+
  24. 18 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 [bioset]
  25. 19 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 [bioset]
  26. 20 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 [bioset]

或者你也可以使用以下格式在远程系统上运行多条命令:



  1. $ ssh [email protected] << EOF
  2. hostnamectl
  3. free -m
  4. grep daygeek /etc/passwd
  5. EOF

上面命令的输出如下:



  1. Pseudo-terminal will not be allocated because stdin is not a terminal.
  2. Static hostname: CentOS7.2daygeek.com
  3. Icon name: computer-vm
  4. Chassis: vm
  5. Machine ID: 002f47b82af248f5be1d67b67e03514c
  6. Boot ID: dca9a1ba06374d7d96678f9461752482
  7. Virtualization: kvm
  8. Operating System: CentOS Linux 7 (Core)
  9. CPE OS Name: cpe:/o:centos:centos:7
  10. Kernel: Linux 3.10.0-957.el7.x86_64
  11. Architecture: x86-64
  12. total used free shared buff/cache available
  13. Mem: 1838 335 1146 11 355 1314
  14. Swap: 2047 0 2047
  15. daygeek:x:1000:1000:2daygeek:/home/daygeek:/bin/bash

7) 如何在远程系统上运行本地 Bash 脚本

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行本地 bash 脚本 remote-test.sh

创建一个 shell 脚本并执行它。



  1. $ vi /tmp/remote-test.sh
  2. #!/bin/bash
  3. #Name: remote-test.sh
  4. #--------------------
  5. uptime
  6. free -m
  7. df -h
  8. uname -a
  9. hostnamectl

上面命令的输出如下:



  1. $ ssh [email protected] 'bash -s' < /tmp/remote-test.sh
  2. 01:17:09 up 22 min, 1 user, load average: 0.00, 0.02, 0.08
  3. total used free shared buff/cache available
  4. Mem: 1838 333 1148 11 355 1316
  5. Swap: 2047 0 2047
  6. Filesystem Size Used Avail Use% Mounted on
  7. /dev/mapper/centos-root 27G 4.4G 23G 17% /
  8. devtmpfs 903M 0 903M 0% /dev
  9. tmpfs 920M 0 920M 0% /dev/shm
  10. tmpfs 920M 9.3M 910M 2% /run
  11. tmpfs 920M 0 920M 0% /sys/fs/cgroup
  12. /dev/sda1 1014M 179M 836M 18% /boot
  13. tmpfs 184M 12K 184M 1% /run/user/42
  14. tmpfs 184M 0 184M 0% /run/user/1000
  15. Linux CentOS7.2daygeek.com 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  16. Static hostname: CentOS7.2daygeek.com
  17. Icon name: computer-vm
  18. Chassis: vm
  19. Machine ID: 002f47b82af248f5be1d67b67e03514c
  20. Boot ID: dca9a1ba06374d7d96678f9461752482
  21. Virtualization: kvm
  22. Operating System: CentOS Linux 7 (Core)
  23. CPE OS Name: cpe:/o:centos:centos:7
  24. Kernel: Linux 3.10.0-957.el7.x86_64
  25. Architecture: x86-64

或者也可以使用管道。如果你觉得输出不太好看,再做点修改让它更优雅些。



  1. $ vi /tmp/remote-test-1.sh
  2. #!/bin/bash
  3. #Name: remote-test.sh
  4. echo "---------System Uptime--------------------------------------------"
  5. uptime
  6. echo -e "\n"
  7. echo "---------Memory Usage---------------------------------------------"
  8. free -m
  9. echo -e "\n"
  10. echo "---------Disk Usage-----------------------------------------------"
  11. df -h
  12. echo -e "\n"
  13. echo "---------Kernel Version-------------------------------------------"
  14. uname -a
  15. echo -e "\n"
  16. echo "---------HostName Info--------------------------------------------"
  17. hostnamectl
  18. echo "------------------------------------------------------------------"

上面脚本的输出如下:



  1. $ cat /tmp/remote-test.sh | ssh [email protected]
  2. Pseudo-terminal will not be allocated because stdin is not a terminal.
  3. ---------System Uptime--------------------------------------------
  4. 03:14:09 up 2:19, 1 user, load average: 0.00, 0.01, 0.05
  5. ---------Memory Usage---------------------------------------------
  6. total used free shared buff/cache available
  7. Mem: 1838 376 1063 11 398 1253
  8. Swap: 2047 0 2047
  9. ---------Disk Usage-----------------------------------------------
  10. Filesystem Size Used Avail Use% Mounted on
  11. /dev/mapper/centos-root 27G 4.4G 23G 17% /
  12. devtmpfs 903M 0 903M 0% /dev
  13. tmpfs 920M 0 920M 0% /dev/shm
  14. tmpfs 920M 9.3M 910M 2% /run
  15. tmpfs 920M 0 920M 0% /sys/fs/cgroup
  16. /dev/sda1 1014M 179M 836M 18% /boot
  17. tmpfs 184M 12K 184M 1% /run/user/42
  18. tmpfs 184M 0 184M 0% /run/user/1000
  19. tmpfs 184M 0 184M 0% /run/user/0
  20. ---------Kernel Version-------------------------------------------
  21. Linux CentOS7.2daygeek.com 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  22. ---------HostName Info--------------------------------------------
  23. Static hostname: CentOS7.2daygeek.com
  24. Icon name: computer-vm
  25. Chassis: vm
  26. Machine ID: 002f47b82af248f5be1d67b67e03514c
  27. Boot ID: dca9a1ba06374d7d96678f9461752482
  28. Virtualization: kvm
  29. Operating System: CentOS Linux 7 (Core)
  30. CPE OS Name: cpe:/o:centos:centos:7
  31. Kernel: Linux 3.10.0-957.el7.x86_64
  32. Architecture: x86-64

8) 如何同时在多个远程系统上运行多条指令

下面的 bash 脚本允许用户同时在多个远程系统上运行多条指令。使用简单的 for 循环实现。

为了实现这个目的,你可以尝试 PSSH 命令ClusterShell 命令DSH 命令



  1. $ vi /tmp/multiple-host.sh
  2. for host in CentOS7.2daygeek.com CentOS6.2daygeek.com
  3. do
  4. ssh daygeek@${host} "uname -a;uptime;date;w"
  5. done

上面脚本的输出如下:



  1. $ sh multiple-host.sh
  2. Linux CentOS7.2daygeek.com 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  3. 01:33:57 up 39 min, 1 user, load average: 0.07, 0.06, 0.06
  4. Wed Sep 25 01:33:57 CDT 2019
  5. 01:33:57 up 39 min, 1 user, load average: 0.07, 0.06, 0.06
  6. USER TTY FROM [email protected] IDLE JCPU PCPU WHAT
  7. daygeek pts/0 192.168.1.6 01:08 23:25 0.06s 0.06s -bash
  8. Linux CentOS6.2daygeek.com 2.6.32-754.el6.x86_64 #1 SMP Tue Jun 19 21:26:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  9. 23:33:58 up 39 min, 0 users, load average: 0.00, 0.00, 0.00
  10. Tue Sep 24 23:33:58 MST 2019
  11. 23:33:58 up 39 min, 0 users, load average: 0.00, 0.00, 0.00
  12. USER TTY FROM [email protected] IDLE JCPU PCPU WHAT

9) 如何使用 sshpass 命令添加一个密码

如果你觉得每次输入密码很麻烦,我建议你视你的需求选择以下方法中的一项来解决这个问题。

如果你经常进行类似的操作,我建议你设置 免密码认证,因为它是标准且永久的解决方案。

如果你一个月只是执行几次这些任务,我推荐你使用 sshpass 工具。只需要使用 -p 参数选项提供你的密码即可。



  1. $ sshpass -p '在这里输入你的密码' ssh -p 2200 [email protected] ip a
  2. 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
  3. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  4. inet 127.0.0.1/8 scope host lo
  5. valid_lft forever preferred_lft forever
  6. inet6 ::1/128 scope host
  7. valid_lft forever preferred_lft forever
  8. 2: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
  9. link/ether 08:00:27:18:90:7f brd ff:ff:ff:ff:ff:ff
  10. inet 192.168.1.12/24 brd 192.168.1.255 scope global dynamic eth0
  11. valid_lft 86145sec preferred_lft 86145sec
  12. inet6 fe80::a00:27ff:fe18:907f/64 scope link tentative dadfailed
  13. valid_lft forever preferred_lft forever

via: https://www.2daygeek.com/execute-run-linux-commands-remote-system-over-ssh/

作者:Magesh Maruthamuthu 选题:lujun9972 译者:alim0x 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

linisi.svg


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK