python ssh模块stdout.read 和recv_Python3之paramiko模块

一. 简介

paramiko是一个基于SSH用于连接远程服务器并执行相关操作(SSHClient和SFTPClinet,即一个是远程连接,一个是上传下载服务),使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实。

二. 使用

1. 下载安装

pycrypto,由于 paramiko 模块内部依赖pycrypto,所以先下载安装pycrypto

pip3 install pycrypto

pip3 install paramiko

2. 模块使用

SSHClient:

远程连接分为两种:(1)基于用户名密码连接 (2)基于公钥秘钥连接

通过是用paramiko远程操作,其实本质也分为两种:(1)只用SSHClient (2)自己创建一个transport

(1)基于用户名和密码的连接

1 import paramiko

2

3 # 创建SSH对象

4 ssh = paramiko.SSHClient()

5 # 允许连接不在know_hosts文件中的主机

6 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

7 # 连接服务器

8 ssh.connect(hostname='c1.salt.com', port=22, username='GSuser', password='123')

9 # 执行命令

10 stdin, stdout, stderr = ssh.exec_command('ls')

11 # 获取命令结果

12 result = stdout.read()

13 # 关闭连接

14 ssh.close()

SSHClient 封装 Transport

1 import paramiko

2

3 transport = paramiko.Transport(('hostname', 22))

4 transport.connect(username='GSuser', password='123')

5

6 ssh = paramiko.SSHClient()

7 ssh._transport = transport

8

9 stdin, stdout, stderr = ssh.exec_command('df')

10 print(stdout.read())

11

12 transport.close()

(2)基于公钥秘钥连接

1 import paramiko

2

3 private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')

4 # 创建SSH对象

5 ssh = paramiko.SSHClient()

6 # 允许连接不在know_hosts文件中的主机

7 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

8 # 连接服务器

9 ssh.connect(hostname='c1.salt.com', port=22, username='wupeiqi', key=private_key)

10 # 执行命令

11 stdin, stdout, stderr = ssh.exec_command('df')

12 # 获取命令结果

13 result = stdout.read()

14 # 关闭连接

15 ssh.close()

SSHClient 封装Transport

1 import paramiko

2

3 private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')

4 transport = paramiko.Transport(('hostname', 22))

5 transport.connect(username='wupeiqi', pkey=private_key)

6 ssh = paramiko.SSHClient()

7 ssh._transport = transport

8 stdin, stdout, stderr = ssh.exec_command('df')

9 transport.close()

SFTPClient:

用于连接远程服务器并进行上传下载功能。

(1)基于用户名密码上传下载

1 import paramiko

2

3 transport = paramiko.Transport(('hostname',22))

4 transport.connect(username='GSuser',password='123')

5

6 sftp = paramiko.SFTPClient.from_transport(transport)

7 # 将location.py 上传至服务器 /tmp/test.py

8 sftp.put('/tmp/location.py', '/tmp/test.py')

9 # 将remove_path 下载到本地 local_path

10 sftp.get('remove_path', 'local_path')

11

12 transport.close()

(2)基于公钥秘钥上传下载

1 import paramiko

2

3 private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')

4

5 transport = paramiko.Transport(('hostname', 22))

6 transport.connect(username='GSuser', pkey=private_key )

7

8 sftp = paramiko.SFTPClient.from_transport(transport)

9 # 将location.py 上传至服务器 /tmp/test.py

10 sftp.put('/tmp/location.py', '/tmp/test.py')

11 # 将remove_path 下载到本地 local_path

12 sftp.get('remove_path', 'local_path')

13

14 transport.close()

Demo: 实现远程命令执行和文件上传

1 #!/usr/bin/env python

2 # -*- coding:utf-8 -*-

3 import paramiko

4

5 class SSHConnection(object):

6

7 def __init__(self, host='192.168.12.68', port=22, username='locojoy',pwd='123321QQ!'):

8 self.host = host

9 self.port = port

10 self.username = username

11 self.pwd = pwd

12 self.__k = None

13

14 def run(self):

15 self.connect() # 连接远程服务器

16 self.upload('db.py','/tmp/1.py') # 将本地的db.py文件上传到远端服务器的/tmp/目录下并改名为1.py

17 self.cmd('df') # 执行df 命令

18 self.close() # 关闭连接

19

20 def connect(self):

21 transport = paramiko.Transport((self.host, self.port))

22 transport.connect(username=self.username, password=self.pwd)

23 self.__transport = transport

24

25 def close(self):

26 self.__transport.close()

27

28 def upload(self,local_path,target_path):

29 sftp = paramiko.SFTPClient.from_transport(self.__transport)

30 sftp.put(local_path,target_path)

31

32 def cmd(self, command):

33 ssh = paramiko.SSHClient()

34 ssh._transport = self.__transport

35 # 执行命令

36 stdin, stdout, stderr = ssh.exec_command(command)

37 # 获取命令结果

38 result = stdout.read()

39 print(result)

40 return result

41

42 obj = SSHConnection()

43 obj.run()

paramiko在堡垒机中的应用

(1)简单实例:远程连接一台主机,操作命令,linux版本,输入终端为回车则发送命令。不支持tab补全功能。

1 import paramiko, sys, os, socket, select, getpass

2 from paramiko.py3compat import u # 在python3中是这样使用的,如果在Python2中则注释这行

3

4 # 这个程序依赖于终端,只能在Liunx下运行,windows用其他的方式

5

6 tran = paramiko.Transport(('192.168.12.68', 22,))

7 tran.start_client()

8 tran.auth_password('locojoy', '123321QQ!')

9

10 # 打开一个通道

11 chan = tran.open_session()

12 # 获取一个终端

13 chan.get_pty()

14 # 激活器

15 chan.invoke_shell()

16

17 # 原始的方法利用终端进行收发消息

18 # 利用sys.stdin,肆意妄为执行操作

19 # 用户在终端输入内容,并将内容发送至远程服务器

20 # 远程服务器执行命令,并将结果返回

21 # 用户终端显示内容

22

23 while True:

24 # 监视用户输入和服务器返回数据

25 # sys.stdin 处理用户输入

26 # chan 是之前创建的通道,用于接收服务器返回信息

27 # 通过select监听终端(输入输出),一旦变化,就将拿到的数据发送给服务器

28 # 通过监听socket句柄,如果有变化表示服务器要给我发消息

29 readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)

30 # 通过select.select 监听chan(打开的通道(和远程服务器连接的状态)), sys.stdin(输入),一旦变化就写入readable

31 # 当chan变化时,加入到readable,远程服务器发送内容过来

32 if chan in readable:

33 try:

34 x = u(chan.recv(1024)) # Python3用这个

35 # x = chan.recv(1024) Python2使用这个

36 if len(x) == 0:

37 print('\r\n*** EOF\r\n')

38 break

39 sys.stdout.write(x) # 写入缓冲区

40 sys.stdout.flush() # 刷新,将缓冲区内容显示出来

41 except socket.timeout:

42 pass

43 # 当sys.stdin 放入readable中时,将获取到的内容发送到远程服务器

44 if sys.stdin in readable:

45 inp = sys.stdin.readline()

46 chan.sendall(inp)

47

48 chan.close()

49 tran.close()

(2)每按一个键就发送记录,并支持tab自动补全

1 import paramiko, sys, os, socket, select, getpass, termios, tty

2 from paramiko.py3compat import u

3

4 tran = paramiko.Transport(('10.211.55.4', 22,))

5 tran.start_client()

6 tran.auth_password('wupeiqi', '123')

7 # 打开一个通道

8 chan = tran.open_session()

9 # 获取一个终端

10 chan.get_pty()

11 # 激活器

12 chan.invoke_shell()

13

14 # 获取原tty属性

15 oldtty = termios.tcgetattr(sys.stdin)

16 try:

17 # 为tty设置新属性

18 # 默认当前tty设备属性:

19 # 输入一行回车,执行

20 # CTRL+C 进程退出,遇到特殊字符,特殊处理。

21 # 这是为原始模式,不认识所有特殊符号

22 # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器

23 tty.setraw(sys.stdin.fileno()) # 恢复终端原始状态,每按一个键就发送

24 chan.settimeout(0.0)

25

26 while True:

27 # 监视 用户输入 和 远程服务器返回数据(socket)

28 # 阻塞,直到句柄可读

29 r, w, e = select.select([chan, sys.stdin], [], [], 1)

30 if chan in r: # 获取服务返回的内容

31 try:

32 x = u(chan.recv(1024))

33 if len(x) == 0:

34 print('\r\n*** EOF\r\n')

35 break

36 sys.stdout.write(x)

37 sys.stdout.flush()

38 except socket.timeout:

39 pass

40 if sys.stdin in r: # 发送命令

41 x = sys.stdin.read(1) # 读取一个字符

42 if len(x) == 0:

43 break

44 chan.send(x) # 发送一个字符

45

46 finally:

47 # 重新设置终端属性,将终端状态还原

48 termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)

49

50 chan.close()

51 tran.close()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值