paramiko
该模块基于SSH用于连接远程服务器并执行相关操作
SSHClient
远程连接服务器有两种方法:SSHClient、tranceport
用于连接远程服务器并执行基本命令
基于用户名密码连接:
1 import paramiko 2 # 创建SSH对象 3 ssh = paramiko.SSHClient() 4 # 允许连接不在know_hosts文件中的主机 5 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 6 # 连接服务器 7 ssh.connect(hostname='192.168.247.131', port=22, username='root', password='111111') 8 # 执行命令 9 stdin, stdout, stderr = ssh.exec_command('pwd') 10 # 获取命令结果 11 result = stdout.read() 12 print(result) 13 # 关闭连接 14 ssh.close()
SSHClient封装transport
1 import paramiko 2 3 transport = paramiko.Transport(('hostname', 22)) 4 transport.connect(username='wupeiqi', 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()
基于公钥密钥连接:
1 import paramiko 2 private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa') 3 # 创建SSH对象 4 ssh = paramiko.SSHClient() 5 # 允许连接不在know_hosts文件中的主机 6 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 7 # 连接服务器 8 ssh.connect(hostname='192.168.247.131', port=22, username='root', key=private_key) 9 # 执行命令 10 stdin, stdout, stderr = ssh.exec_command('df') 11 # 获取命令结果 12 result = stdout.read() 13 14 15 16 # 关闭连接 17 18 ssh.close()
封装
import paramiko private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa') transport = paramiko.Transport(('hostname', 22)) transport.connect(username='wupeiqi', pkey=private_key) ssh = paramiko.SSHClient() ssh._transport = transport stdin, stdout, stderr = ssh.exec_command('df') transport.close()
SFTPClient
实现文件下载的方法:Tranceport
用于连接远程服务器并执行上传下载
基于用户名密码上传下载
1 import paramiko 2 3 4 5 transport = paramiko.Transport(('hostname',22)) 6 7 transport.connect(username='wupeiqi',password='123') 8 9 10 11 sftp = paramiko.SFTPClient.from_transport(transport) 12 13 # 将location.py 上传至服务器 /tmp/test.py 14 15 sftp.put('/tmp/location.py', '/tmp/test.py') 16 17 # 将remove_path 下载到本地 local_path 18 19 sftp.get('remove_path', 'local_path') 20 21 22 23 transport.close()
基于公钥密钥上传下载
import paramiko private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa') transport = paramiko.Transport(('hostname', 22)) transport.connect(username='wupeiqi', pkey=private_key ) sftp = paramiko.SFTPClient.from_transport(transport) # 将location.py 上传至服务器 /tmp/test.py sftp.put('/tmp/location.py', '/tmp/test.py') # 将remove_path 下载到本地 local_path sftp.get('remove_path', 'local_path') transport.close()
通过以上分析,可以知道,如果想实现远程连接执行命令,只能使用tranceport方法。
通过利用transport和SSHClient实现在一次链接中多次执行命令和上传、下载文件。
1 import paramiko 2 import uuid 3 class SSHConnection(object): 4 def __init__(self,host='192.168.247.131',port=22,username='root',pwd='111111'): 5 self.host = host 6 self.port = port 7 self.username = username 8 self.pwd = pwd 9 self._k = None 10 11 def run(self): 12 self.connect() 13 pass 14 self.close() 15 16 def connect(self): 17 transport = paramiko.Transport((self.host,self.port)) 18 transport.connect(username=self.username,password=self.pwd) 19 self.__transport = transport 20 def close(self): 21 self.__transport.close() 22 def cmd(self,command): 23 ssh = paramiko.SSHClient() 24 ssh._transport = self.__transport 25 stdin,stdout,stderr = ssh.exec_command(command) 26 result = stdout.read() 27 return result 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 create_file(self): 33 file_name = str(uuid.uuid4()) 34 with open(file_name, 'w') as f: 35 f.write('sb') 36 return file_name 37 ssh = SSHConnection() 38 #上传文件、执行命令 39 ssh.connect() 40 r1 = ssh.cmd('df') 41 print(r1) 42 ssh.upload('s2.py','/home/s7.py') 43 ssh.close()
上面的例子是将命令写入代码中,并返回执行结果,下面我们就来介绍通过终端输入命令,等待返回结果:
1.输入命令点回车,执行命令,等待结果(linux终端默认只有点击回车,io中的stdin才会有变化),不支持tab补全
2.每输入一个字就给服务器传过去,然后再点回车,服务器执行传来的命令。(改变终端的模式)
第一个实例
1 import paramiko 2 import sys 3 import os 4 import socket 5 import select 6 import getpass 7 # from paramiko.py3compat import u py27需要注释 8 tran = paramiko.Transport(('192.168.247.128',22,)) 9 tran.start_client() 10 tran.auth_password('root','111111') 11 #打开一个通道 12 chan = tran.open_session() 13 #获取一个通道 14 chan.get_pty() 15 #激活器 16 chan.invoke_shell() 17 while True: 18 #监视用户输入和服务器返回数据 19 #sys.stdin 处理用户输入 20 #chan是之前创建的通道,用于就收服务器返回信息 21 readable,writeable,error = select.select([chan,sys.stdin,],[],[],1) 22 if chan in readable: #此处的chan是服务器通过执行命令,返回的结果 23 try: 24 #x = u(chan.recv(1024)) 25 x = chan.recv(1024) #py27写法 26 if len(x) == 0: 27 print('\r\n*** EOF\r\n') 28 break 29 sys.stdout.write(x) 30 sys.stdout.flush() #刷新缓冲区,将内容打印到屏幕 31 except socket.timeout: 32 pass 33 if sys.stdin in readable: 34 inp = sys.stdin.readline() 35 chan.sendall(inp) 36 chan.close() 37 tran.close()
第二个实例
1 import paramiko 2 import sys 3 import os 4 import socket 5 import select 6 import getpass 7 import tty 8 import termios 9 # from paramiko.py3compat import u py27需要注释 10 tran = paramiko.Transport(('192.168.247.128',22,)) 11 tran.start_client() 12 tran.auth_password('lwq','123') 13 #打开一个通道 14 chan = tran.open_session() 15 #获取一个通道 16 chan.get_pty() 17 #激活器 18 chan.invoke_shell() 19 #获取原tty属性,目的是为了在操作完以后恢复终端原型 20 oldtty = termios.tcgetattr(sys.stdin) 21 try: 22 #为tty设置新属性 23 #默认当前tty设备属性 24 #输入一行回车,执行 25 #ctrl +c 进程退出,遇到特殊字符,特殊处理 26 #这是为原始模式,不认识特殊字符号 27 #放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到 远程服务器 28 tty.setraw(sys.stdin.fileno()) 29 chan.settimeout(0.0) 30 while True: 31 #监视用户输入和服务器返回数据 32 #阻塞,直到句柄可读 33 readable,writeable,error = select.select([chan,sys.stdin,],[],[],1) 34 if chan in readable: 35 try: 36 #x = u(chan.recv(1024)) 37 x = chan.recv(1024) #py27写法 38 if len(x) == 0: 39 print('\r\n*** EOF\r\n') 40 break 41 sys.stdout.write(x) 42 sys.stdout.flush() 43 except socket.timeout: 44 pass 45 if sys.stdin in readable: 46 inp = sys.stdin.read(1) 47 if len(inp) == 0: 48 break 49 chan.send(inp) 50 finally: 51 #重新设置终端属性 52 termios.tcsetattr(sys.stdin,termios.TCSADRAIN,oldtty) 53 chan.close() 54 tran.close()