原文: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