python paramiko

Win7下Python2.7環境安裝paramiko模塊

Win7下Python2.7環境安裝paramiko模塊,有需要的朋友可以參考下

近段時間用Python寫一個小東西,每次修改代碼後要手工上傳到服務器,覺得很麻煩,雖然有WinSCP,找了一下資料,發現paramiko可以實現自動上傳文件的功能,可惜的是,折騰了半天,在Python3.3下沒有成功,最後退而求其次安裝了2.7才弄好,記錄如下:

1.下載安裝Windows版本的Python2.7,我默認裝在C:\Python27

2.下載PyCrypto2.6 for Python 2.7 64bit
地址爲http://www.voidspace.org.uk/python/modules.shtml#pycrypto
以管理員權限執行安裝程序,一路Next即可

3.下載安裝ecdsa-0.10.tar.gz,地址 https://pypi.python.org/packages/source/e/ecdsa/ecdsa-0.10.tar.gz 解壓縮
進入安裝目錄,執行 C:\Python27\python setup.py install

4.下載paramiko壓縮包
地址:https://pypi.python.org/packages/source/p/paramiko/paramiko-1.12.1.tar.gz

解壓縮後從cmd進入解壓縮目錄,執行命令
C:\Python27\python setup.sh install

5.確認安裝成功
在cmd中執行C:\Python27\python進入python環境
輸入import paramiko無錯誤提示則表示安裝成功

 

paramiko是用python語言寫的一個模塊,遵循SSH2協議,支持以加密和認證的方式,進行遠程服務器的連接了,下面我們就來給各位一起驗證一下python模塊paramikossh安裝與使用示例吧。

一、paramiko模塊的安裝
paramiko模塊依賴PyCrypto模塊,而PyCrypto需要GCC庫編譯,不過一般發行版的源裏帶有該模塊。這裏以centos6爲例,直接藉助以下命令可以直接完成安裝:

 代碼如下

複製代碼

# yum install gcc python-crypto python-paramiko python-devel  -y 

windows版下可以安裝windows版的GCC(MinGW),然後編輯安裝pycrypto和paramiko ,下載安成後,直接運行python.exe setup.pybuild 和 python.exe setup.py install 就可以了。

二、paramiko的連接
使用paramiko模塊有兩種連接方式,一種是通過paramiko.SSHClient()函數,另外一種是通過paramiko.Transport()函數。

方法一:

 代碼如下

複製代碼

import paramiko
 ssh = paramiko.SSHClient()
 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
 ssh.connect("
某IP地址",22,"用戶名", "口令")

上面的第二行代碼的作用是允許連接不在know_hosts文件中的主機。

方法二:

 代碼如下

複製代碼

import paramiko
 t = paramiko.Transport(("
主機","端口"))
 t.connect(username = "用戶名", password = "口令")

如果連接遠程主機需要提供密鑰,上面第二行代碼可改成:

 代碼如下

複製代碼

t.connect(username = "用戶名", password = "口令",  hostkey="密鑰")

三、paramiko ssh連接
以下是一個簡單的通過paramiko模塊定義的ssh連接並執行命令的函數,如下:

 代碼如下

複製代碼

#!/usr/bin/python
 #-*- coding: utf-8 -*-
 import paramiko
 #paramiko.util.log_to_file('/tmp/sshout')
 def ssh2(ip,username,passwd,cmd):
     try:
         ssh = paramiko.SSHClient()
          ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
          ssh.connect(ip,22,username,passwd,timeout=5)
         stdin,stdout,stderr =  ssh.exec_command(cmd)
 #            stdin.write("Y")   #
簡單交互,輸入 ‘Y’
         print stdout.read()
 #        for x in   stdout.readlines():
 #          print x.strip("\n")
         print '%s\tOK\n'%(ip)
         ssh.close()
     except :
         print '%s\tError\n'%(ip)
 ssh2("192.168.0.102","root","361way","hostname;ifconfig")
 ssh2("192.168.0.107","root","123456","ifconfig")

其中第四行的日誌部分,是記錄ssh連接交互時的一些信息,可以看做是類似於debug的輸出,一般情況下不需要開啓。

stdin.write部分是用於交互情況下,通過該命令可以執行交互。注意這裏可能會引起歧義,這裏的交互並不是ssh連接過程中出現的讓輸入 yes的交互,因爲paramiko模塊在連接過程中會自動處理好yes確認。這裏的交互是指後面的cmd需要的執行的程序可能出現交互的情況下,可以通 過該參數進行交互。

stdout標準輸出,在輸出內容比較少時,可以通過直接使用read讀取出所有的輸出;但在輸出內容比較多時,建議通過按行讀取進行處理。不過按行讀取時,每行結尾會有換行符\n,這樣輸出的結果很不美觀。可以通過strip進行字符串的處理。

在函數調用過程中需要注意的是,IP、username、passwd都是屬於字符串型的,所以需要加引號。後面執行的cmd,如果有多個命令需要操作時,需要通過分號進行分割。

四、paramiko sftp示例
單個文件小傳下載的示例:

 代碼如下

複製代碼

import paramiko
 #
建立一個加密的管道
 scp=paramiko.Transport(('192.168.0.102',22))
 #建立連接
 scp.connect(username='root',password='361way')
 #建立一個sftp客戶端對象,通過ssh  transport操作遠程文件
 sftp=paramiko.SFTPClient.from_transport(scp)
 #Copy a remote file (remotepath) from the SFTP server to the local host
 sftp.get('/root/testfile','/tmp/361way')
 #Copy a local file (localpath) to the SFTP server as remotepath
 sftp.put('/root/crash-6.1.6.tar.gz','/tmp/crash-6.1.6.tar.gz')
 scp.close()

一個目錄下多個文件上傳下載的示例:

 代碼如下

複製代碼

#!/usr/bin/env python
 #-*- coding: utf-8 -*-
 import paramiko,datetime,os
 hostname='192.168.0.102'
 username='root'
 password='361way'
 port=22
 local_dir='/tmp/getfile'
 remote_dir='/tmp/abc'
 try:
     t=paramiko.Transport((hostname,port))
     t.connect(username=username,password=password)
     sftp=paramiko.SFTPClient.from_transport(t)
     #files=sftp.listdir(dir_path)
     files=sftp.listdir(remote_dir)
     for f in files:
         print ''
         print  '#########################################'
         print 'Beginning to download  file  from %s  %s ' % (hostname,datetime.datetime.now())
         print 'Downloading  file:',os.path.join(remote_dir,f)
          sftp.get(os.path.join(remote_dir,f),os.path.join(local_dir,f))#
下載
          #sftp.put(os.path.join(local_dir,f),os.path.join(remote_dir,f))#上傳
         print 'Download file success %s '  % datetime.datetime.now()
         print ''
         print  '##########################################'
     t.close()
 except Exception:
        print "connect error!" 

注:本處的目錄下所有文件進行下載或上傳的示例中,在遇到目錄下還有嵌套的目錄存在時,會將目錄也當做文件進行處理,所以如果想要更加的完美的話,可以通過引入stat模塊下的S_ISDIR方法進行處理

paramiko.transport對象也支持以socket的方式進行連接,如下示例:

 代碼如下

複製代碼

import paramiko
 transport = paramiko.Transport(('localhost',22))
 transport.connect(username='root', password = 'password')
 sftp = paramiko.SFTPClient.from_transport(transport)
 sftp.get(remotefile,localfile)
 #
如果是上傳則用:
 #sftp.put(localfile, remotefile)
 transport.close()
 #用socket連接
 tcpsock =  socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 tcpsock.settimeout(5)
 tcpsock.connect((ip,22),)
 ssh = paramiko.Transport(tcpsock)
 ssh.connect(username=user,password=password)
 sftpConnect=paramiko.SFTPClient.from_transport(ssh)

五、利用paramiko實現ssh的交互式連接
以下是通過paramiko模塊直接用ssh協議登陸到遠程服務器的操作代碼,這裏先定義一個interactive模塊,代碼如下:

 代碼如下

複製代碼

import socket
 import sys
 # windows does not have termios...
 try:
     import termios
     import tty
     has_termios = True
 except ImportError:
     has_termios = False
 def interactive_shell(chan):
     if has_termios:
         posix_shell(chan)
     else:
         windows_shell(chan)
 def posix_shell(chan):
     import select
     oldtty = termios.tcgetattr(sys.stdin)
     try:
         tty.setraw(sys.stdin.fileno())
         tty.setcbreak(sys.stdin.fileno())
         chan.settimeout(0.0)
         while True:
             r, w, e =  select.select([chan, sys.stdin], [], [])
             if chan in  r:
                  try:
                      x = chan.recv(1024)
                      if len(x) == 0:
                          print '
\r\n*** EOF\r\n',
                          break
                      sys.stdout.write(x)
                      sys.stdout.flush()
                  except socket.timeout:
                      pass
             if  sys.stdin in r:
                  x = sys.stdin.read(1)
                  if len(x) == 0:
                      break
                  chan.send(x)
     finally:
         termios.tcsetattr(sys.stdin,  termios.TCSADRAIN, oldtty)
 # thanks to Mike Looijmans for this code
 def windows_shell(chan):
     import threading
     sys.stdout.write("Line-buffered terminal emulation.  Press F6 or ^Z to send EOF.\r\n\r\n")
     def writeall(sock):
         while True:
             data =  sock.recv(256)
             if not  data:
                  sys.stdout.write('\r\n*** EOF  ***\r\n\r\n')
                  sys.stdout.flush()
                  break
              sys.stdout.write(data)
              sys.stdout.flush()
     writer = threading.Thread(target=writeall, args=(chan,))
     writer.start()
     try:
         while True:
             d =  sys.stdin.read(1)
             if not d:
                  break
              chan.send(d)
     except EOFError:
         # user hit ^Z or F6
         pass

代碼內容可以從paramiko 在github項目上的demo裏獲取。再另外寫一個ssh_inter.py的交互主程序,內容如下:

 代碼如下

複製代碼

import paramiko
 import interactive
 #
記錄日誌
 paramiko.util.log_to_file('/tmp/test')
 #建立ssh連接
 ssh=paramiko.SSHClient()
 ssh.load_system_host_keys()
 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
 ssh.connect('192.168.0.102',port=22,username='root',password='xxxxxx',compress=True)
 #建立交互式shell連接
 channel=ssh.invoke_shell()
 #建立交互式管道
 interactive.interactive_shell(channel)
 #關閉連接
 channel.close()
 ssh.close()

執行效果就像我們平時直接使用ssh登錄一樣。

六、總結
paramiko模塊是一個比較強大的ssh連接模塊,以上的示例只是列出了該模塊的一些簡單的使用方法,還可以使用threading模塊加塊程序併發 的速度;也可以使用configparser模塊處理配置文件,而我們將所有IP、用戶信息操作都放入配置文件;使用setproctitle模塊爲執行 的程序加一個容易區分的title等。

同樣,雖然連fabric這樣大名鼎鼎的軟件使用的ssh都是用paramiko模塊進行的封裝,不過你依然可以選擇不使用它,你也可以選擇pexpect模塊實現封裝一個簡易的ssh連接工具、或者使用同樣比較火的salt-ssh模塊。

paramiko模塊是基於Python實現的ssh遠程安全鏈接,實現命令遠程、文件傳輸、SSH代理等功能。本文詳細介紹了paramiko模塊常用的方法,且實用價值非常高,稍作修改就能做出一個實用的運維工具。

 

安裝

letong@me:~$ sudo pip install paramiko

 

簡單的遠程執行命令實例

#!/usr/bin/env python
import paramiko
hostname='127.0.0.1'
username='root'
password='123456'
port=2222
 
ssh=paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.connect(hostname=hostname,port=port,username=username,password=password)
stdin,stdout,stderr=ssh.exec_command('ls /')
print stdout.read()
ssh.close()

 

SSHClient

SSHClient類是SSH服務會話的高級表示,封裝了傳輸、通道以及SFTPClient的校驗、建立方法,通常用於執行命令。

connect方法

connect(self, hostname, port=22, username=None,password=None, pkey=None, Key_filename=None, timeout=None, allow_agent=True,look_for_keys=True, compress=False)

參數說明:

hostname,連接目標的主機地址
port,連接目標的端口,默認22
username,用戶名
password,用戶密碼
pkey,私鑰方式用戶驗證
key_filename,私鑰文件名
timeout,超時時間
allow_agent,是否允許ssh代理
look_for_keys,是否允許搜索私鑰文件
compress,打開時是否壓縮

 

exec_command方法

exec_command(self, command, bufzise=-1)

參數說明:

command,執行的命令
bufsize,文件緩衝區大小,-1不限制

 

load_system_host_keys方法

load_system_host_keys(self, filename=None)

參數說明:

filename,指定遠程主機公鑰文件

 

set_missing_host_key_policy方法

ssh=paramiko.SSHClient()

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

參數說明:

AutoAddPolicy,自動添加主機名及密鑰到本地並保存,不依賴load_system_host_keys()配置
RejectPolicy,自動拒絕未知主機名和密鑰,依賴load_system_host_keys()配置
WarnningPolicy,功能與AutoAddPolicy相同,但是未知主機會報警

 

SFTPClient

根據SSH傳輸協議的sftp會話,實現遠程文件上傳、下載等操作。

from_transport方法

from_transport(cls, t)

參數說明:

t,一個已通過驗證的傳輸對象

例:

>>> import paramiko
>>> a = paramiko.Transport((“127.0.0.1″,2222))
>>> a.connect(username=”root”, password=’123456′)
>>> sftp = paramiko.SFTPClient.from_transport(a)

 

put方法

put(self, localpath, remotepath, callback=None,confirm=True)

參數說明:

localpath,上傳源文件的本地路徑
remotepath,目標路徑
callback,獲取接收與總傳輸字節數
confirm,上傳完畢後是否調用stat()方法,以便確認文件大小

例:

>>> localpath=’ftp-test.log’
>>> remotepath=’/data/ftp-test.log’
>>> sftp.put(localpath,remotepath)

 

get方法

get(self, remotepath, localpath, callback=None)

參數說明:

remotepath,需要下載的遠程文件
localpath,本地存儲路徑
callback,同put方法

 

其他方法

mkdir,用於創建目錄
remove,刪除目錄
rename,重命名
stat,獲取文件信息
listdir,獲取目錄列表

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章