【轉】ssh 遠程執行命令


原文:https://blog.csdn.net/liuxiao723846/article/details/82667482

 

SSH 是 Linux 下進行遠程連接的基本工具,不光可以登錄,也可以遠程操作。接下來我們詳細講解一些常用的情況。

1、執行簡單的命令:

1)查看某台主機上的磁盤使用情況:

$ ssh root@1.113.195.138 "df -h"
***************************************************************************
NOTICE TO Users

This computer system is the private property of ...

***************************************************************************

Filesystem Size Used Avail Use% Mounted on
/dev/vda2 36G 3.2G 31G 10% /
tmpfs 25G 0 25G 0% /dev/shm
/dev/vdb 296G 2.0G 279G 1% /data

可以看到會把ssh遠程連接的信息,以及遠程執行名的返回的信息都輸出到了控制台上。

2)保存遠程執行命令結果:

有時我們需要保存遠程執行命令的結果,然后進行判斷。有兩種方法:

賦值的方式:result=`ssh x@B ~/command.sh`
追加到文件:ssh root@$ip "cmd" >> ./log

詳情見:https://blog.csdn.net/liuxiao723846/article/details/55045988

3)一次執行多個命令:

在shell中單行語句一般要用到分號來區分代碼塊,多行的話用換行符來區分代碼塊,則無需用到分號。

$ if [ "$PS1" ]; then echo test is ok; fi
test is ok

如果換做多行
$if [ "PS1" ]
> then echo "test is ok"
> fi
test is ok

所以,我們可以在ssh中用分好拼接多個命令

1 ssh root@$IP "if [ -e /lib64/libpcre.so.1 ];then echo 'file exits...';else cd /lib64 && ln -s libpcre.so.0.0.1 libpcre.so.1;fi"

2、執行需要交互的命令:

有時候我們需要遠程執行一些有交互操作的命令,如下:

$ ssh nick@xxx.xxx.xxx.xxx "sudo ls /root"
$ ssh nick@xxx.xxx.xxx.xxx "top"

這兩條命令雖然提示的失敗原因不同,但它們有一個共同點:都需要與用戶交互(需要 TTY)。所以它們失敗的原因也是相同的:
默認情況下,當你執行不帶命令的 ssh 連接時,會為你分配一個 TTY。因為此時你應該是想要運行一個 shell 會話。
但是當你通過 ssh 在遠程主機上執行命令時,並不會為這個遠程會話分配 TTY。此時 ssh 會立即退出遠程主機,所以需要交互的命令也隨之結束。
好在我們可以通過 -t 參數顯式的告訴 ssh,我們需要一個 TTY 遠程 shell 進行交互!
添加 -t 參數后,ssh 會保持登錄狀態,直到你退出需要交互的命令。

3、執行本地腳本:

通常我們遇到的不會是上面那種簡單的問題,大多數時候我們需要把若干個命令放到一個腳本里,然后分發到遠程去執行。大致有兩種思路:

使用scp將本地腳本文件拷貝到遠端,然后再通過ssh執行遠端的腳本;(弊端是腳本修改后,每次都需要scp)
直接在本地執行腳本到遠程;
一個scp的例子

1 for IP in ${IP_ARR[@]}
2 do
3 ssh root@$IP "rm -rf $MONITOR_TARGET_FILE" 
4 ssh root@$IP "mkdir -p /data/apps/scripts"
5 scp $MONITOR_SOURCE_FILE root@$IP:$MONITOR_TARGET_FILE
6 ssh root@$IP 'echo "*/1 * * * * /usr/bin/python /data/apps/scripts/checkStatus.py' $BUSINESS_TYPE '>/dev/null 2>&1" >> /var/spool/cron/root'
7 
8 done

重點我們在如何在本地執行腳本到遠程。

1)執行一個簡單的腳本到遠程:

1 $ cat test.sh 
2 ls
3 pwd
4 
5 $ ssh root@10.153.195.138 < test.sh 
6 anaconda-ks.cfg
7 /root

通過重定向 stdin,本地的腳本 test.sh 在遠程服務器上被執行。

2)為腳本傳遞參數:

 1 $ cat test.sh 
 2 echo $1
 3 echo $2
 4 
 5 在本地執行結構如下:
 6 $ sh test.sh a b
 7 a
 8 b
 9 
10 通過重定向遠程執行,會報錯
11 $ ssh root@10.153.195.138 < test.sh a b
12 bash: a: command not found

看來上面的方法都無法為腳本傳遞參數。
要想在這種情況下(遠程執行本地的腳本)執行帶有參數的腳本,需要為 bash 指定 -s 參數:

1 $ ssh root@10.153.195.138 'bash -s' < test.sh a b
2 a
3 b

除此之外,我們還可以通過替換的方式傳參,然后遠程執行,例如:

1 cat ./rollback_remote.sh | sed -e "s/#module#/${MODULE_NAME}/g" -e "s/#runarg#/${RUN_ARG}/g" | ssh $IP

4、執行遠程服務器上的腳本:

除了執行本地的腳本,還有一種情況是腳本文件存放在遠程服務器上,而我們需要遠程的執行它!此時在遠程服務器上用戶 nick 的家目錄中有一個腳本 test.sh。文件的內容如下:

1 ls
2 pwd
3 執行下面的命令即可(注:一定是絕對路徑):
4 $ ssh nick@xxx.xxx.xxx.xxx "/home/nick/test.sh"

下面我們也嘗試為腳本傳遞參數。在遠程主機上的 test.sh 文件的末尾添加兩行:

1 echo $0
2 echo $1
3 然后嘗試執行下面的命令:
4 
5 $ ssh nick@xxx.xxx.xxx.xxx /home/nick/test.sh helloworld

可以正確得到結果。

5、執行多行命令:

有時候我們可能需要隨手寫幾行簡單的邏輯,這也沒有問題,ssh 能輕松搞定!

1 $ ssh root@10.153.195.138 "
2 > ls
3 > pwd
4 > "
5 anaconda-ks.cfg
6 /root

你可以用單引號或雙引號開頭,然后寫上幾行命令,最后再用相同的引號來結束。

當我們在命令中引用了變量時會怎么樣呢?

1 $ name=test
2 $ ssh root@10.153.195.138 "
3 > echo $name
4 > "
5 test
6 
7 $ ssh root@10.153.195.138 '
8 echo $name
9 '

最后一行,並沒有輸出我們期望的 test。這里多少有些詭異,因為如果變量沒有被解釋的話,輸出的應該是 $name 才對。但是這里卻什么都沒有輸出。對於引用變量的寫法,可以通過bash 指定了 -c 參數方式保證變量被正確解釋:

1 $ ssh root@10.153.195.138 bash -c "'
2 echo $name
3 '"
4 test

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM