python模块paramiko与ssh

简介:

  paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。paramiko支持Linux, Solaris, BSD, MacOS X, Windows等平台通过SSH从一个平台连接到另外一个平台。利用该模块,可以方便的进行ssh连接和sftp协议进行sftp文件传输。


一、安装

paramiko模块依赖PyCrypto模块,而PyCrypto需要GCC库编译,不过一般发行版的源里带有该模块。centos6,直接借助以下命令可以直接完成安装:

 

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


windows的话,可以下载二进制包

PyCrypto:http://www.voidspace.org.uk/python/pycrypto-2.6.1/ 下一步下一步安装即可

paramiko:https://pypi.python.org/pypi/paramiko/1.7.4  解压缩,然后进入解压缩目录,在DOS下执行

python setup.py build
python setup.py install

或者

pip install paramiko

二、paramiko的连接

使用paramiko模块有两种连接方式,一种是通过paramiko.SSHClient()函数,另外一种是通过paramiko.Transport()函数。

方法一:

1
2
3
4
import  paramiko
ssh  =  paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect( "某IP地址" , 22 , "用户名" "口令" )

上面的第二行代码的作用是允许连接不在know_hosts文件中的主机。

方法二:

1
2
3
import  paramiko
=  paramiko.Transport(( "主机" , "端口" ))
t.connect(username  =  "用户名" , password  =  "口令" )

如果连接远程主机需要提供密钥,上面第二行代码可改成:

1
t.connect(username  =  "用户名" , password  =  "口令" , hostkey = "密钥" )

三、paramiko ssh连接

以下是一个简单的通过paramiko模块定义的ssh连接并执行命令的函数,如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/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  '%stOKn' % (ip)
         ssh.close()
     except  :
         print  '%stErrorn' % (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示例

单个文件小传下载的示例:

1
2
3
4
5
6
7
8
9
10
11
12
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()

一个目录下多个文件上传下载的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/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  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的方式进行连接,如下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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模块,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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 :
                     =  chan.recv( 1024 )
                     if  len (x)  = =  0 :
                         print  'rn*** EOFrn' ,
                         break
                     sys.stdout.write(x)
                     sys.stdout.flush()
                 except  socket.timeout:
                     pass
             if  sys.stdin  in  r:
                 =  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.rnrn" )
     def  writeall(sock):
         while  True :
             data  =  sock.recv( 256 )
             if  not  data:
                 sys.stdout.write( 'rn*** EOF ***rnrn' )
                 sys.stdout.flush()
                 break
             sys.stdout.write(data)
             sys.stdout.flush()
     writer  =  threading.Thread(target = writeall, args = (chan,))
     writer.start()
     try :
         while  True :
             =  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的交互主程序,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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模块。



本文转自 baby神 51CTO博客,原文链接:http://blog.51cto.com/babyshen/1887832,如需转载请自行联系原作者

相关文章
|
4天前
|
Java 程序员 开发者
Python的gc模块
Python的gc模块
|
7天前
|
数据采集 Web App开发 JavaScript
python-selenium模块详解!!!
Selenium 是一个强大的自动化测试工具,支持 Python 调用浏览器进行网页抓取。本文介绍了 Selenium 的安装、基本使用、元素定位、高级操作等内容。主要内容包括:发送请求、加载网页、元素定位、处理 Cookie、无头浏览器设置、页面等待、窗口和 iframe 切换等。通过示例代码帮助读者快速掌握 Selenium 的核心功能。
37 5
|
8天前
|
Python
SciPy 教程 之 SciPy 模块列表 13
SciPy教程之SciPy模块列表13:单位类型。常量模块包含多种单位,如公制、二进制(字节)、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率和力学单位。示例代码展示了如何使用`constants`模块获取零摄氏度对应的开尔文值(273.15)和华氏度与摄氏度的转换系数(0.5556)。
12 1
|
8天前
|
XML 前端开发 数据格式
超级详细的python中bs4模块详解
Beautiful Soup 是一个用于从网页中抓取数据的 Python 库,提供了简单易用的函数来处理导航、搜索和修改分析树。支持多种解析器,如 Python 标准库中的 HTML 解析器和更强大的 lxml 解析器。通过简单的代码即可实现复杂的数据抓取任务。本文介绍了 Beautiful Soup 的安装、基本使用、对象类型、文档树遍历和搜索方法,以及 CSS 选择器的使用。
22 1
|
9天前
|
Python
SciPy 教程 之 SciPy 模块列表 9
SciPy教程之常量模块介绍,涵盖多种单位类型,如公制、质量、角度、时间、长度、压强等。示例展示了如何使用`scipy.constants`模块查询不同压强单位对应的帕斯卡值,包括atm、bar、torr、mmHg和psi。
10 1
|
6天前
|
Python
SciPy 教程 之 SciPy 模块列表 16
SciPy教程之SciPy模块列表16 - 单位类型。常量模块包含多种单位,如公制、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率和力学单位。示例代码展示了力学单位的使用,如牛顿、磅力和千克力等。
10 0
|
6天前
|
JavaScript Python
SciPy 教程 之 SciPy 模块列表 15
SciPy 教程之 SciPy 模块列表 15 - 功率单位。常量模块包含多种单位,如公制、质量、时间等。功率单位中,1 瓦特定义为 1 焦耳/秒,表示每秒转换或耗散的能量速率。示例代码展示了如何使用 `constants` 模块获取马力值(745.6998715822701)。
10 0
|
6天前
|
JavaScript Python
SciPy 教程 之 SciPy 模块列表 15
SciPy教程之SciPy模块列表15:单位类型。常量模块包含多种单位,如公制、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率和力学单位。功率单位以瓦特(W)表示,1W=1J/s。示例代码展示了如何使用`constants`模块获取马力(hp)的值,结果为745.6998715822701。
11 0
|
8天前
|
Python
SciPy 教程 之 SciPy 模块列表 13
SciPy 教程之 SciPy 模块列表 13 - 单位类型。常量模块包含多种单位:公制、二进制(字节)、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率和力学单位。示例:`constants.zero_Celsius` 返回 273.15 开尔文,`constants.degree_Fahrenheit` 返回 0.5555555555555556。
9 0
|
8天前
|
Python
SciPy 教程 之 SciPy 模块列表 11
SciPy教程之SciPy模块列表11:单位类型。常量模块包含公制单位、质量单位、角度换算、时间单位、长度单位、压强单位、体积单位、速度单位、温度单位、能量单位、功率单位、力学单位等。体积单位示例展示了不同体积单位的换算,如升、加仑、流体盎司、桶等。
9 0