1. 程式人生 > >shell 遠端執行命令

shell 遠端執行命令

轉自:https://www.cnblogs.com/softidea/p/6855045.html
shell遠端執行:
  經常需要遠端到其他節點上執行一些shell命令,如果分別ssh到每臺主機上再去執行很麻煩,因此能有個集中管理的方式就好了。一下介紹兩種shell命令遠端執行的方法。

前提條件:
  配置ssh免密碼登陸

對於簡單的命令:
  如果是簡單執行幾個命令,則:

ssh [email protected] “cd /home ; ls”
  基本能完成常用的對於遠端節點的管理了,幾個注意的點:

雙引號,必須有。如果不加雙引號,第二個ls命令在本地執行
分號,兩個命令之間用分號隔開
對於指令碼的方式:
  有些遠端執行的命令內容較多,單一命令無法完成,考慮指令碼方式實現:

複製程式碼

!/bin/bash

ssh [email protected] > /dev/null 2>&1 << eeooff
cd /home
touch abcdefg.txt
exit
eeooff
echo done!
複製程式碼
遠端執行的內容在“<< eeooff ” 至“ eeooff ”之間,在遠端機器上的操作就位於其中,注意的點:

<< eeooff,ssh後直到遇到eeooff這樣的內容結束,eeooff可以隨便修改成其他形式。
重定向目的在於不顯示遠端的輸出了
在結束前,加exit退出遠端節點

http://www.cnblogs.com/ilfmonday/p/ShellRemote.html

目錄 [隱藏]

1 SSH命令格式
2 主要引數說明
3 ssh控制遠端主機,遠端執行命令步驟
4 準備工作
5 基於公私鑰認證遠端登入可能存在的不足
6 ssh 執行遠端命令格式
6.1 開啟遠端shell
7 ssh的-t引數
SSH命令格式
usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
[-D [bind_address:]port] [-e escape_char] [-F configfile]
[-I pkcs11] [-i identity_file]
[-L [bind_address:]port:host:hostport]
[-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
[-R [bind_address:]port:host:hostport] [-S ctl_path]
[-W host:port] [-w local_tun[:remote_tun]]
[

[email protected]]hostname [command]
主要引數說明
-l 指定登入使用者
-p 設定埠號
-f 後臺執行,並推薦加上 -n 引數
-n 將標準輸入重定向到 /dev/null,防止讀取標準輸入。如果在後臺執行ssh的話(-f選項),就需要這個選項。
-N 不執行遠端命令,只做埠轉發
-q 安靜模式,忽略一切對話和錯誤提示
-T 禁用偽終端配置
-t (tty)為遠端系統上的ssh程序分配一個偽tty(終端)。如果沒有使用這個選項,當你在遠端系統上執行某條命令的時候,ssh不會為該程序分配tty(終端)。相反,ssh將會把遠端程序的標準輸入和標準輸出附加到ssh會話上去,這通常就是你所希望的(但並非總是如此)。這個選項將強制ssh在遠端系統上分配tty,這樣那些需要tty的程式就能夠正常執行。
-v verbose)顯示與連線和傳送有關的除錯資訊。如果命令執行不太正常的話,這個選項就會非常有用。

ssh控制遠端主機,遠端執行命令步驟
第一步,設定ssh免認證,免認證就是不用密碼認證就可以直接登入,這在寫指令碼伺服器控制時特別有用。

每二步,就是到遠端伺服器上去執行命令

準備工作
基於公私鑰認證(可參考:Linux配置SSH金鑰登入詳解及客戶端測試使用無密碼登入)或者使用者名稱密碼認證(可參考:SSH使用expect自動輸入密碼、命令實現非互動式密碼授權)能確保登入到遠端伺服器
cmd如果是指令碼,注意絕對路徑問題(相對路徑在遠端執行時就是坑)

基於公私鑰認證遠端登入可能存在的不足
這個可以滿足我們大多數的需求,但是通常運維部署很多東西的時候需要root許可權,但是有幾處限制:
遠端伺服器禁止root使用者登入
在遠端伺服器腳本里轉換身份用expect需要send密碼,這樣不夠安全

ssh 執行遠端命令格式
ssh [options] [[email protected]]host [command]
其中,host為想要連線到的OpenSSH伺服器(遠端系統)的名稱,它是惟一的必需引數。host可以是某個本地系統的名稱,也可以是因特網上某個系統的FQDN(參見術語表)或者是一個IP地址。命令ssh host登入到遠端系統host,使用的使用者名稱與正在本地系統上使用的使用者名稱完全相同。如果希望登入的使用者名稱與正在本地系統上使用的使用者名稱不同,那麼就應該包含[email protected]。根據伺服器設定的不同,可能還需要提供口令。

開啟遠端shell
如果沒有提供command引數,ssh就會讓你登入到host上去。遠端系統顯示一個shell提示符,然後就能夠在host上執行命令。命令exit將會關閉與host的連線,並返回到本地系統的提示符。

例:命令列執行登入並且在目標伺服器上執行命令

ssh [email protected] “cd /home ; ls”
基本能完成常用的對於遠端節點的管理了,幾個注意的點:
如果想在遠端機器上連續執行多條命令,可以用單引號或者雙引號將這些命令括起來。如果不加單引號或者雙引號,第二個ls命令在本地執行。例如 ssh [email protected] cd /local ls 則 ls 只會執行 cd /local 命令,ls命令在本地執行,加了雙引號或者單引號,則被括起來的命令被當做ssh命令的一個引數,所以會在遠端連續執行。
分號,兩個命令之間用分號隔開

例:在目標伺服器上執行批量的命令。

!/bin/bash

ssh [email protected] < < remotessh
killall -9 java
cd /data/apache-tomcat-7.0.53/webapps/
exit
remotessh
遠端執行的內容在”< < remotessh ” 至” remotessh “之間,在遠端機器上的操作就位於其中,注意的點:<< remotessh,ssh後直到遇到remotessh這樣的內容結束,remotessh可以隨便修改成其他形式。在結束前,加exit退出遠端節點 如果不想日誌檔案在本機出現可以修改配置

ssh [email protected] > /dev/null 2>&1 < < remotessh
ssh的-t引數
-t Force pseudo-tty allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty.
中文翻譯一下:就是可以提供一個遠端伺服器的虛擬tty終端,加上這個引數我們就可以在遠端伺服器的虛擬終端上輸入自己的提權密碼了,非常安全
命令格式

ssh -t -p port[email protected]$ip ‘cmd’
示例指令碼

!/bin/bash

變數定義

ip_array=(“192.168.1.1” “192.168.1.2” “192.168.1.3”)
user=”test1”
remote_cmd=”/home/test/1.sh”

本地通過ssh執行遠端伺服器的指令碼

for ip in iparray[]doif[ip = “192.168.1.1” ]; then
port=”7777”
else
port=”22”
fi
ssh -t -p port[email protected]$ip “remote_cmd”
done
這個方法還是很方便的,-t虛擬出一個遠端伺服器的終端,在多臺伺服器同時部署時確實節約了不少時間啊!

例:檢視遠端伺服器的cpu資訊
假設遠端伺服器IP是192.168.110.34
ssh -l www-online 192.168.110.34 “cat /proc/cpuinfo”

例:執行遠端伺服器的sh檔案
首先在遠端伺服器的/home/www-online/下建立一個uptimelog.sh指令碼

!/bin/bash

uptime >> ‘uptime.log’

exit 0
使用chmod增加可執行許可權

chmod u+x uptimelog.sh
在本地呼叫遠端的uptimelog.sh

ssh -l www-online 192.168.110.34 “/home/www-online/uptimelog.sh”
執行完成後,在遠端伺服器的/home/www-online/中會看到uptime.log檔案,顯示uptime內容

[email protected]:~$ tail -f uptime.log
21:07:34 up 288 days, 8:07, 1 user, load average: 0.05, 0.19, 0.31
例:執行遠端後臺執行sh
首先把uptimelog.sh修改一下,修改成迴圈執行的命令。作用是每一秒把uptime寫入uptime.log

!/bin/bash

while :
do
uptime >> ‘uptime.log’
sleep 1
done

exit 0
我們需要這個sh在遠端伺服器以後臺方式執行,命令如下:
ssh -l www-online 192.168.110.34 “/home/www-online/uptimelog.sh &”

[email protected]:~$ ssh -l www-online 192.168.110.34 “/home/www-online/uptimelog.sh &”
[email protected]’s password:
輸入密碼後,發現一直停住了,而在遠端伺服器可以看到,程式已經以後臺方式運行了。

[email protected]:~$ ps aux|grep uptimelog.sh
1007 20791 0.0 0.0 10720 1432 ? S 21:25 0:00 /bin/bash /home/www-online/uptimelog.sh
原因是因為uptimelog.sh一直在執行,並沒有任何返回,因此呼叫方一直處於等待狀態。
我們先kill掉遠端伺服器的uptimelog.sh程序,然後對應此問題進行解決。

ssh 呼叫遠端命令後不能自動退出解決方法
可以將標準輸出與標準錯誤輸出重定向到/dev/null,這樣就不會一直處於等待狀態。
ssh -l www-online 192.168.110.34 “/home/www-online/uptimelog.sh > /dev/null 2>&1 &”

[email protected]:~ssh -l www-online 192.168.110.34 “/home/www-online/uptimelog.sh > /dev/null 2>&1 &”  [email protected]’s password:  [email protected]:~
但這個ssh程序會一直執行在後臺,浪費資源,因此我們需要自動清理這些程序。

實際上,想ssh退出,我們可以在ssh執行完成後kill掉ssh這個程序來實現。
首先,建立一個sh執行ssh的命令,這裡需要用到ssh的 -f 與 -n 引數,因為我們需要ssh也以後臺方式執行,這樣才可以獲取到程序號進行kill操作。
建立ssh_uptimelog.sh,指令碼如下

!/bin/bash

ssh -f -n -l www-online 192.168.110.34 “/home/www-online/uptimelog.sh &” # 後臺執行ssh

pid=(ps aux | grep "ssh -f -n -l www-online 192.168.110.34 /home/www-online/uptimelog.sh" | awk '{print2}’ | sort -n | head -n 1) # 獲取程序號

echo “ssh command is running, pid:${pid}”

sleep 3 && kill ${pid} && echo “ssh command is complete” # 延遲3秒後執行kill命令,關閉ssh程序,延遲時間可以根據呼叫的命令不同調整

exit 0
可以看到,3秒後會自動退出

[email protected]:~./sshuptimelog.shwwwonline@192.168.110.34spassword:sshcommandisrunning,pid:10141sshcommandiscompletewwwonline@onlinedev01:
然後檢視遠端伺服器,可以見到uptimelog.sh 在後臺正常執行。

[email protected]:~$ ps aux|grep uptime
1007 28061 0.1 0.0 10720 1432 ? S 22:05 0:00 /bin/bash /home/www-online/uptimelog.sh
檢視uptime.log,每秒都有uptime資料寫入。

[email protected]:~$ tail -f uptime.log
22:05:44 up 288 days, 9:05, 1 user, load average: 0.01, 0.03, 0.08
22:05:45 up 288 days, 9:05, 1 user, load average: 0.01, 0.03, 0.08
22:05:46 up 288 days, 9:05, 1 user, load average: 0.01, 0.03, 0.08
22:05:47 up 288 days, 9:05, 1 user, load average: 0.01, 0.03, 0.08
22:05:48 up 288 days, 9:05, 1 user, load average: 0.01, 0.03, 0.08
附錄:
1、單引號和雙引號在ssh命令中的區別:
以一個例子來說明問題,

假設本地機器上配置了JAVA環境變數,在本地執行 echo $JAVA_HOME=/opt/jdk

假若我想檢視遠端機器上的JAVA環境變數,則只能使用單引號了,ssh [email protected] ‘ echo JAVA,JAVA不會被shell解析,而是當做一個字串,此時引數 echo $JAVA 傳遞給了 ssh;

如果我們使用 ssh [email protected] ” echo JAVAshellJAVA,得到它的值,則該命令就變成了 ssh [email protected] ‘ echo /opt/jdk ‘ 了

2、可能遇到的問題
問題:遠端登入主機時出現Pseudo-terminal will not be allocated because stdin is not a terminal. 錯誤
解決方案:字面意思是偽終端將無法分配,因為標準輸入不是終端。

所以需要增加-t -t引數來強制偽終端分配,即使標準輸入不是終端。
to force pseudo-tty allocation even if stdin isn’t a terminal.

參考樣例如下:
ssh -t -t [email protected] -p 9527

相關推薦

Linux Shell遠端執行命令命令列與指令碼方式)

shell遠端執行:  經常需要遠端到其他節點上執行一些shell命令,如果分別ssh到每臺主機上再去執行很麻煩,因此能有個集中管理的方式就好了。一下介紹兩種shell命令遠端執行的方法。 前提條件:   配置ssh免密碼登陸 對於簡單的命令:   如果是簡單執行幾個命令,則: ssh [em

shell 遠端執行命令

轉自:https://www.cnblogs.com/softidea/p/6855045.html shell遠端執行:   經常需要遠端到其他節點上執行一些shell命令,如果分別ssh到每臺主機上再去執行很麻煩,因此能有個集中管理的方式就好了。一下介紹

Linux遠端拷貝&遠端執行命令shell指令碼

很多時候linux伺服器管理、釋出程式碼等,通常需要兩個工具,一個是遠端拷貝,一個是遠端執行命令,下面介紹兩個比較好用的指令碼,實現這兩個功能。 需要安裝expect,遠端執行命令,centos下直接yum -y install expect,不能yum安裝下

第三十三天 遠端執行命令與粘包問題

上週回顧: 1.三層結構   一種程式的框架   使用者檢視   與使用者互動 接受和輸出資料   業務邏輯   複雜對資料進行  判斷  驗證  組裝   資料訪問層 複雜處理資料的存取   2.異常處理   異常處理的目的是為了

python指令碼實現本地或遠端執行命令

功能:1、執行本地shell命令,執行完成後獲取結果2、執行本地shell命令,執行中實時獲取輸出結果3、執行遠端shell命令,執行完成後獲取結果4、執行遠端shell命令,執行中實時獲取輸出結果 實際操作:1、安裝paramiko apt-get install python3-pip libev

遠端執行命令,監控伺服器

http://a.scwy.net/blog/doc/177 通過ssh,遠端監控伺服器,獲取伺服器資訊。這裡主要是作一下記錄,怕忘。 for ((c=1;;i++)); do sshpass -p 1234567 ssh [email protected] "uptime

ssh 遠端執行命令

SSH 是 Linux 下進行遠端連線的基本工具,不光可以登入,也可以遠端操作。接下來我們詳細講解一些常用的情況。 1、執行簡單的命令: 1)檢視某臺主機上的磁碟使用情況: $ ssh [email protected] "df -h" ***********

Python開源Devops定時任務管理系統(含定時呼叫介面、定時ssh遠端執行命令

 OpenMangosteen Devops定時呼叫http介面,定時執行SSH命令的WEB定時任務工具。本系統強依賴Flask-APScheduler的功能,只是拓展了web頁面部分。使用Pytho

python利用paramiko實現ssh連線及遠端執行命令

python3.6, windows下 1,安裝paramiko模組 依賴cryptography:使用命令easy_install安裝該模組時,如果報錯“...microsoft visual c++ 14.0 is required.”, 可以下載.whl檔案,使用命令pip instal

大作業11-指令碼批量遠端執行命令

然後再寫一個通用的可以批量遠端執行命令的expect指令碼: [[email protected] ~]# vim cmd.expect #!/usr/bin/expect set user [lindex $argv 0]  # 系統使用者 set host

linux不開賬號允許遠端執行命令

2016-09-21 周海漢 2016.9.21 如果允許使用者可以遠端執行一些linux命令,但並不希望在系統中給使用者單獨建立賬號。而每個使用者還需要隔離,需要認證是否是系統允許的合法使用者。同時需要限制操作的範圍和許可權

ssh遠端執行命令並自動退出

ssh命令格式如下: usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D

shell遠端執行 遠端執行指令碼

對於簡單的命令: 如果是簡單執行幾個命令,則 ssh [email protected] "cd /home ; ls" 指令碼如下 #!/bin/bash for node in `cat nodelist` do echo "-------

ssh遠端執行命令

我們直接可以通過ssh命令,直接遠端機器執行命令,那麼我們是不是就可以通過用for迴圈的命令對遠端的機器安裝服務了呢。。 ssh   [email protected]  “yum -y install nginx” 通過上面的命令,可以實現批量

Linux下使用SSH非互動式遠端執行命令指令碼

原創文章,轉載請註明— 作者: 黃文海 出處: http://viscent.iteye.com/http://blog.viscenthuang.info     非互動式在遠端主機上執行命令或者指令碼可以幫助我們快速完成一些任務。比如,在叢集環境中,同時在各個結點上的日

expect指令碼同步檔案,expect指令碼指定host和要同步的檔案,構建檔案分發系統,批量遠端執行命令

expect指令碼同步檔案 在一臺機器上把檔案同步到多臺機器上 自動同步檔案 #!/usr/bin/expect set passwd "123456" spawn rsync -av [email protected]:/tmp/12.txt /tmp/ ex

JSch連線SSH遠端執行命令

package test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Arr

十七週四次課 2018.03.05 expect指令碼同步檔案、expect指令碼指定host和要同步的檔案、構建檔案分發系統、批量遠端執行命令

20.31 expect指令碼同步檔案 在一臺機器上把檔案同步到另外一臺機器上去。 建立檔案,然後把上面的程式碼貼上進去, 把尾號132的遠端機器的12.txt同步到本機的/tmp/目錄下 第一次登入問提示是否登入,第二次就可以直接輸密碼登入了。 表示expect結束了,

關於ansible模組無法遠端執行命令不成功總結

由於使用ansible指令碼批量化部署環境,網路環境走的代理,但是有些模組總是無法執行成功,最後經過排查是因為ansible遠端連線通過ssh,無法獲取環境變數,我的環境變數是在/etc/profile檔案裡。可以通過shell命令先匯入環境變數 ssh ro

linux shell程式設計執行命令kill掉指定名稱的程序

 在linux開發中我們時常會遇到對於之前程序kill掉,然後再運行當前程序或程式的情況,此時我們是不知道需要kill的程序號的,那麼就需要通過一個shell命令組合來實現這個需求,如下命令就可以實現: 命令:ps -efww | grep -w 'nameprocess'