通過 SSH 在遠程 Linux 系統上執行命令
通過安全的網路連接在遠程計算機上調用命令或程序。
有一天,我正在測試如何在 將文件或目錄複製到多個位置和系統時保持完整的文件許可權。當我想檢查遠程系統上的文件許可權時,我必須通過 SSH 登錄它並檢查屬性。從遠程系統多次登錄和註銷的過程讓我有點煩,我想,如果我可以在遠程 Linux 系統上通過 SSH 執行命令就好了。
幸運的是,在瀏覽了 ssh
命令的手冊頁後,我找到了一個解決辦法。
如果你想知道如何本地運行遠程系統上運行命令或腳本,而不登錄到遠程系統,下面的內容會告訴你如何做。
1、通過 SSH 在遠程 Linux 系統上執行命令
從本地系統通過 SSH 在遠程系統上運行命令或腳本的典型方法是:
$ ssh <username@IP_Address-or-Doman_name> <Command-or-Script>
允許我給你們舉幾個例子:
1.1、通過 SSH 在遠程系統上運行單個命令
假設你想要 查找遠程 Linux 系統的內核詳細信息。為此,只需運行:
$ ssh sk@192.168.225.22 uname -a
這裡,
sk
是遠程系統的用戶名,192.168.225.22
是遠程系統的 IP 地址,uname -a
是我想在遠程系統上運行的命令。
示例輸出:
看到沒?我並沒有實際登錄到遠程系統,但通過 SSH 在遠程系統上執行了 uname
命令,並在本地系統的終端上顯示了輸出。
你還可以像下面這樣用引號指定命令。
$ ssh sk@192.168.225.22 "uname -a"
或者,
$ ssh sk@192.168.225.22 'uname -a'
如果你已經 更改了 SSH 協議的默認埠,只需使用 -p
參數指定它。
$ ssh -p 2200 sk@192.168.225.22 uname -a
1.2、通過 SSH 在遠程主機上執行多個命令
你還可以在遠程主機上運行多個命令,方法是將它們放在引號中。
$ ssh sk@192.168.225.22 "uname -r && lsb_release -a"
或者:
$ ssh sk@192.168.225.22 "uname -r ; lsb_release -a"
上面的命令將顯示我的 Ubuntu 伺服器的內核版本和發行版詳細信息。
示例輸出:
正如一位讀者在下面的評論部分提到的那樣,你應該用引號指定多個命令。如果不使用引號,第一個命令將在遠程系統上執行,第二個命令將僅在本地計算機上執行。整個帶引號的命令將按預期在遠程計算機上運行。
提示: 了解
&&
和;
在命令中的區別:
&&
操作符只有在第一個命令成功時才執行第二個命令。示例:
sudo apt-get update && sudo apt-get upgrade
在上述示例中,如果第一個命令成功,才會執行
sudo apt-get upgrade
。否則,它將不會運行。
;
操作符會執行第二個命令,無論第一個命令是成功還是失敗。示例:
sudo apt-get update ; sudo apt-get upgrade
在上述示例中,即使第一個命令失敗,
sudo apt-get upgrade
也會執行。
1.3、通過 SSH 在遠程機器上調用有 sudo 許可權的命令
有些命令需要 sudo
許可權才能運行。例如,以下命令將在我的遠程系統上安裝 apache2
。
$ ssh -t sk@192.168.225.22 sudo apt install apache2
示例輸出:
注意到了嗎?我在上面的命令中使用了 -t
標誌,我們需要使用它來強制進行偽終端分配。它用於在遠程機器上執行任意基於屏幕的程序,這非常有用。例如,在實現菜單服務時。
另外,我輸入了兩次密碼。第一次是遠程用戶的密碼,以便從本地系統通過 SSH 訪問遠程系統,第二次是為了向遠程用戶賦予 sudo 許可權,以便安裝應用程序(在本例中為 apache2)。
讓我們用以下命令檢查 Apache 服務是否正在運行:
$ ssh -t sk@192.168.225.22 sudo systemctl status apache2
sk@192.168.225.22's password:
[sudo] password for sk:
● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
Drop-In: /lib/systemd/system/apache2.service.d
└─apache2-systemd.conf
Active: active (running) since Thu 2019-12-19 11:08:03 UTC; 52s ago
Main PID: 5251 (apache2)
Tasks: 55 (limit: 2318)
CGroup: /system.slice/apache2.service
├─5251 /usr/sbin/apache2 -k start
├─5253 /usr/sbin/apache2 -k start
└─5254 /usr/sbin/apache2 -k start
Dec 19 11:08:03 ubuntuserver systemd[1]: Starting The Apache HTTP Server...
Dec 19 11:08:03 ubuntuserver apachectl[5227]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 2409:4072:51f:a1b6:a00:27ff:f
Dec 19 11:08:03 ubuntuserver systemd[1]: Started The Apache HTTP Server.
同樣的,我們可以通過 SSH 在本地系統上運行遠程系統上的任何命令或腳本。
1.4、通過 SSH 在遠程系統上運行本地腳本
讓我們在本地系統上創建一個簡單的腳本來顯示關於遠程系統的發行版名稱、包管理和基本細節等。
$ vi system_information.sh
添加以下行:
#!/bin/bash
#Name: Display System Details
#Owner: OSTechNIx
#-------------------------echo /etc/*_ver* /etc/*-rel*; cat /etc/*_ver* /etc/*-rel*
按下 ESC
鍵,輸入 :wq
保存退出。
現在,通過 SSH 命令在遠程系統上運行這個腳本:
$ ssh sk@192.168.225.22 'bash -s' < system_information.sh
示例輸出:
sk@192.168.225.22's password:
/etc/debian_version /etc/lsb-release /etc/os-release
buster/sid
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.2 LTS"
NAME="Ubuntu"
VERSION="18.04.2 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.2 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
如果你沒有在上面的命令中指定 bash -s
,你將獲得遠程系統的詳細信息,但偽終端不會被分配。
1.5、將遠程主機的命令輸出保存到本地主機
如果你希望與支持團隊或同事共享遠程系統上運行的命令輸出,那麼這非常有用。
以下命令將通過 SSH 在遠程系統運行 du -ah
,並將輸出保存在本地系統的 diskusage.txt
文件中。
$ ssh sk@192.168.225.22 du -ah > diskusage.txt
然後,你可以通過使用 cat
命令或文本編輯器查看 diskusage.txt
文件來分析磁碟使用細節。
$ cat diskusage.txt
4.0K ./.profile
4.0K ./.gnupg/private-keys-v1.d
8.0K ./.gnupg
76K ./data/image.jpg
128K ./data/file.pdf
20K ./data/text.docx
5.9M ./data/audio.mp3
6.1M ./data
0 ./.sudo_as_admin_successful
4.0K ./pacman?inline=false
4.0K ./.bash_logout
4.0K ./.wget-hsts
4.0K ./.bash_history
0 ./.cache/motd.legal-displayed
4.0K ./.cache
4.0K ./deb-pacman_1.0-0.deb
4.0K ./.bashrc
6.2M .
1.6、配置 SSH 密鑰認證,避免輸入密碼
如果你經常在遠程系統上運行命令,你可能需要配置基於 SSH 密鑰的身份驗證,以便每次跳過密碼輸入。更多細節可以在以下鏈接中找到。
配置了基於 SSH 密鑰的認證後,我們可以通過 SSH 在遠程機器上執行命令,從而不需要輸入密碼:
$ ssh sk@192.168.225.22 sudo apt update
2、通過 sshpass 在遠程機器上運行命令
如果你不想配置基於 SSH 密鑰的身份驗證,你可以使用 sshpass
實用程序。
2.1、什麼是 sshpass?
sshpass
是為使用鍵盤交互密碼身份驗證模式運行 ssh 而設計的,但它以非交互的方式。簡單來說,sshpass
提供了非互動式的方式來驗證 SSH 會話。
SSH 使用直接 TTY 訪問來確保密碼確實是由互動式鍵盤用戶發出的。sshpass
在一個專用 tty 中運行 SSH,讓它誤以為從交互用戶那裡獲得了密碼。
2.2、在 Linux 中安裝 sshpass
在許多 Linux 發行版的默認倉庫中都有 sshpass
實用程序。例如,在 Debian、Ubuntu 及其衍生版本中,你可以使用下面的命令來安裝 sshpass
:
$ sudo apt install sshpass
2.3、通過 SSH 和 sshpass 在遠程機器上執行命令
sshpass
可以通過參數接受密碼,或者通過環境變數讀取密碼,也可以從文本文件中讀取密碼。
警告: 所有這些方法都是 高度不安全的。所有系統用戶都可以通過 ps
命令看到命令中的密碼。不建議在生產中使用這些方法。最好使用基於密鑰的身份驗證。
讓我們看看每種方法的示例。
將密碼作為參數提供
將密碼作為參數提供,使用 -p
選項,如下所示:
$ sshpass -p <remote-password> ssh remoteuser@ip-address <command-to-execute>
示例輸出:
$ sshpass -p ubuntu ssh ostechnix@192.168.1.30 uname -a
其中,
-p ubuntu
- 提供遠程系統的密碼。ostechnix@192.168.1.30
- 遠程系統用戶名和地址。uname -a
- 要在遠程計算機上執行的命令。
示例輸出:
Linux Ubuntu22CT 5.15.60-1-pve #1 SMP PVE 5.15.60-1 (Mon, 19 Sep 2022 17:53:17 +0200) x86_64 x86_64 x86_64 GNU/Linux
密碼作為環境變數提供
在這個方法中,我們聲明一個名為 SSHPASS
的環境變數,用遠程環境的密碼作為其值。然後我們使用 -e
標誌,如下所示:
$ SSHPASS=ubuntu sshpass -e ssh ostechnix@192.168.1.30 uname -a
從文本文件中讀取密碼
使用 echo
命令在文本文件中追加密碼:
$ echo "ubuntu" > mypassword.txt
現在,將密碼文件傳遞給帶有 -f
標誌的 sshpass
,如下所示:
$ sshpass -f mypassword.txt ssh ostechnix@192.168.1.30 uname -a
總結
在本教程中,我們學習了一些通過安全的網路連接在遠程計算機上調用命令或程序的方法。在所有的方法中,sshpass
方法是最不安全的,建議用戶避免在生產系統中使用它。
via: https://ostechnix.com/execute-commands-on-remote-linux-systems-via-ssh/
作者:sk 選題:lkxed 譯者:MjSeven 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive