Python中的SSH

使用SSH client連接可以使用paramiko或者使用Pexpect,這些都可以自動化連接SSH並進行預先安排的操作,只不過,在連接SSH的時候,需要提前準備SSH私鑰,爲了簡便,用openssh自動創建

下載open ssh客戶端(如果用pexpect,那麼可以調用openssh客戶端)

yum install openssh-clients

先下載Pexpect模塊,Pexpect模塊並不是python的標準內置模塊,所以需要先下載安裝纔可以使用

easy_install Pexpect

一切都是自動的,我最喜歡這個了

在調用pxssh進行ssh連接之前,先用ssh客戶端連接一下,以便生成密鑰

ssh –l user –p 22 192.168.1.104

查看密鑰的生成,主要是查看known_hosts

cat ~/.ssh/*

在ipython中導入這個模塊

import pexpect

pexpect模塊中有派生類Pxssh,可以直接建立一個SSH連接,比pexpect直接調用ssh要好使的多

import pxssh

try:


s=pxssh.pxssh()

hostname=’192.168.1.104’

username=’todd’

password=’******’

#調用login()函數

s.login(hostname,username,password)

#調用sendline()函數發送一個命令,例如pwd

s.sendline(‘pwd’)

#調用prompt()等待命令執行完畢

s.prompt()

#before屬性顯示在prompt()函數之前的顯示

s.before

#如果操作系統是中文,那麼避免顯示亂碼,可以使用print()函數

#print(s.before)

s.sendline(‘df -h’)

s.prompt()

print(s.before)

#如果此時再進行ssh連接,個人感覺應該重新建立一個pxssh實例,在遠端機器上繼續運行,沒條件測試


except pxssh.ExceptionPxssh,e:


print( str(e))


這個感覺非常有用,以前在公司裏面就遇到過類似的問題,需要先用ssh登陸到一臺終端上,然後在這個終端上再使用ssh連接到真正的服務器上,在服務器上進行用戶的密碼修改,這個時候ssh的自動登陸連接就起到它應有的作用了。

有條件就來一下模擬,嘿嘿,這個想起來不是很難,可以虛擬出兩臺服務器做這個測試,等有機會再說

除了用pexpect內置的pxssh來連接,還有一種方法是直接調用pexpect來進行ssh訪問,進行自動任務,個人測試了一下,這個方法還是挺好玩的

其中,expect()是正則表達式,可以加很多正則表達式,例如s.expect(‘string1’,’string2’,’string3’),如果符合string1,就返回0,符合string2,就返回1。

看出來了吧,就是返回index值啊,特麼的,害我看下面的代碼,迷糊了半天,下面的代碼說明了這點

index = p.expect (['good', 'bad', pexpect.EOF, pexpect.TIMEOUT])
if index == 0:
   do_something()
elif index == 1:
  do_something_else()
elif index == 2:
  do_some_other_thing()
elif index == 3:
  do_something_completely_different()

使用pexpect類還有一個不方便的地方,就是沒有返回結果,這個問題困擾了我半天,怎麼也找不到解決方法,最後終於找到了,我擦,原來是把返回放到了log裏面

現在寫一個使用openssh client訪問ssh server的自動python腳本,用pexpect類

#!/usr/bin/env python

import pexpect

import sys

s=pexpect.spawn(‘ssh’,[‘[email protected]’])

#將返回寫到屏幕輸出,當然也可以寫到一個文件裏面,以後保存起來

s.logfile_read=sys.stdout

#設置expect的正則表達式,來定位具體的輸出,例如密碼的輸入位置

s.expect(‘password:’)

#調用sendline()來輸出密碼,以後往ssh裏面輸入命令,都需要使用send()或sendline(),具體區別看文檔

s.sendline(‘******’)

#這時候輸入一個命令,例如uname –a

s.sendline(‘uname -a’)

#定位輸出字符串,一般使用上一次輸入的命令即可,例如uname

s.expect(‘uname’)

#這個功能對於一般的腳本來說用處不大,人家直接寫到日誌裏面,誰會給你寫到屏幕上?測試一下還可以,下面是顯示結果

uname -a
Linux python-host 2.6.32-220.4.1.el6.x86_64 #1 SMP Tue Jan 24 02:13:44 GMT 2012 x86_64 x86_64 x86_64 GNU/Linux
[todd@python-host ~]$

#關閉ssh連接

s.close()

 

如果要寫腳本,就必須加上條件判斷,到時候再潤色一下就可以了。

主要參考瞭如下資料

http://pexpect.sourceforge.net/pexpect.html#spawn-send

http://pexpect.sourceforge.net/pxssh.html

http://www.ibm.com/developerworks/cn/linux/l-cn-pexpect1/

http://www.ibm.com/developerworks/cn/linux/l-cn-pexpect2/

IBM裏面的應用不錯,特別是那個登陸FTP下載東西的,如果這樣的話,那麼以後可以做很多事了,Linux真是強大啊,Windows不行啊。

發佈了120 篇原創文章 · 獲贊 8 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章