python_way day13 paramiko
paramiko
一、安装
1 | pip3 install paramiko |
二、使用
1、SSHClient
用于连接远程服务器并执行基本命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname = 'c1.salt.com' , port = 22 , username = 'wupeiqi' , password = '123' ) # 执行命令 stdin, stdout, stderr = ssh.exec_command( 'ls' ) # 获取命令结果 result = stdout.read() # 关闭连接 ssh.close() |
看代码:
1、ssh = paramiko.SSHClient()
def __init__(self):
"""
Create a new SSHClient.
"""
self._system_host_keys = HostKeys()
self._host_keys = HostKeys()
self._host_keys_filename = None
self._log_channel = None
self._policy = RejectPolicy()
self._transport = None
self._agent = None
2、ssh.connect(hostname='c1.salt.com', port=22, username='wupeiqi', password='123')
326 t = self._transport = Transport(sock, gss_kex=gss_kex, gss_deleg_creds=gss_deleg_creds)
#其实SSHClient内部就是定义了transport来链接的

import paramiko #创建transport指定主机地址和端口 transport = paramiko.Transport(('hostname', 22)) #使用transport连接主机 transport.connect(username='wupeiqi', password='123') #创建ssh ssh = paramiko.SSHClient() #赋值transport ssh._transport = transport stdin, stdout, stderr = ssh.exec_command('df') print stdout.read() transport.close()
使用公钥链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import paramiko private_key = paramiko.RSAKey.from_private_key_file( '/home/auto/.ssh/id_rsa' ) # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname = 'c1.salt.com' , port = 22 , username = 'wupeiqi' , key = private_key) # 执行命令 stdin, stdout, stderr = ssh.exec_command( 'df' ) # 获取命令结果 result = stdout.read() # 关闭连接 ssh.close() |

import paramiko #定义秘钥位置 private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa') #创建transport transport = paramiko.Transport(('hostname', 22)) #使用transport 指定用户名,指定秘钥 transport.connect(username='wupeiqi', pkey=private_key) #连接 ssh = paramiko.SSHClient() #使用将transport赋值 ssh._transport = transport #执行命令 stdin, stdout, stderr = ssh.exec_command('df') transport.close()
2、SFTPClient
用于连接远程服务器并执行上传下载
基于用户名密码上传下载:
import paramiko #使用 transport 创建链接 transport = paramiko.Transport(('hostname',22)) transport.connect(username='wupeiqi',password='123') #并且将transport倒入 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() 基于公钥密钥上传下载:
3、总结通过上面的ssh 和 sftp 可以看出来paramiko的链接都是使用的transport来实现的
根据上面的例子在一个连接中执行多条命令
import paramiko import uuid class SSHConnection: def __init__(self, host='192.168.109.134', port=22, username='han',pwd='123456'): self.host = host self.port = port self.username = username self.pwd = pwd self.__k = None def connect(self): transport = paramiko.Transport((self.host,self.port)) transport.connect(username=self.username,password=self.pwd) self.__transport = transport #创建transport def close(self): #关闭连接 self.__transport.close() def upload(self,local_path, target_path): # 连接,上传,local_path 本地文件,target_path目标地址 sftp = paramiko.SFTPClient.from_transport(self.__transport) sftp.put(local_path, target_path) def rename(self, old_path, new_path): ssh = paramiko.SSHClient() ssh._transport = self.__transport # 执行命令 cmd = "mv %s %s" % (old_path, new_path,) stdin, stdout, stderr = ssh.exec_command(cmd) # 获取命令结果 result = stdout.read() def cmd(self, command): ssh = paramiko.SSHClient() ssh._transport = self.__transport # 执行命令 stdin, stdout, stderr = ssh.exec_command(command) # 获取命令结果 result = stdout.read() return result connect = SSHConnection() connect.connect() before = connect.cmd('ls /home/han') print(before.decode()) connect.upload('sshclient.py','/home/han/sshclient1.py') after = connect.cmd('ls /home/han') connect.close() print(after.decode())

#!/usr/bin/env python # -*- coding:utf-8 -*- import paramiko import uuid class SSHConnection(object): def __init__(self, host='172.16.103.191', port=22, username='wupeiqi',pwd='123'): self.host = host self.port = port self.username = username self.pwd = pwd self.__k = None def create_file(self): file_name = str(uuid.uuid4()) with open(file_name,'w') as f: f.write('sb') return file_name def run(self): self.connect() self.upload('/home/wupeiqi/tttttttttttt.py') self.rename('/home/wupeiqi/tttttttttttt.py', '/home/wupeiqi/ooooooooo.py) self.close() def connect(self): transport = paramiko.Transport((self.host,self.port)) transport.connect(username=self.username,password=self.pwd) self.__transport = transport def close(self): self.__transport.close() def upload(self,target_path): # 连接,上传 file_name = self.create_file() sftp = paramiko.SFTPClient.from_transport(self.__transport) # 将location.py 上传至服务器 /tmp/test.py sftp.put(file_name, target_path) def rename(self, old_path, new_path): ssh = paramiko.SSHClient() ssh._transport = self.__transport # 执行命令 cmd = "mv %s %s" % (old_path, new_path,) stdin, stdout, stderr = ssh.exec_command(cmd) # 获取命令结果 result = stdout.read() def cmd(self, command): ssh = paramiko.SSHClient() ssh._transport = self.__transport # 执行命令 stdin, stdout, stderr = ssh.exec_command(command) # 获取命令结果 result = stdout.read() return result ha = SSHConnection() ha.run()
3、利用终端实现xshell的效果

import paramiko import sys import os import socket import select import getpass tran = paramiko.Transport(('192.168.109.134', 22,)) tran.start_client() tran.auth_password('han', '123456') # 打开一个通道 chan = tran.open_session() # 获取一个终端 chan.get_pty() # 激活器这个终端 chan.invoke_shell() ######### 在激活终端和关闭终端之间我们就可以利用终端的sys.stdin执行任意操作 利用sys.stdin,肆意妄为执行操作 用户在终端输入内容,并将内容发送至远程服务器 远程服务器执行命令,并将结果返回 用户终端显示内容 ######### chan.close() tran.close()

import paramiko import sys import os import socket import select import getpass #from paramiko.py3compat import u 有人这么用,没看出有什么效果 tran = paramiko.Transport(('192.168.109.134', 22,)) tran.start_client() tran.auth_password('han', '123456') # 打开一个通道 chan = tran.open_session() # 获取一个终端 chan.get_pty() # 激活器这个终端 chan.invoke_shell() while True: # 监视用户输入和服务器返回数据 # sys.stdin 处理用户输入 # chan 是之前创建的通道,用于接收服务器返回信息 readable, writeable, error = select.select([chan, sys.stdin,],[],[],1) #[chan, sys.stdin, ] #chan 就是 chan = tran.open_session() 这个session的通道,只要这里面有值就证明远程发回了命令 #sys.stdin 就是输入,只要有变化就发生变化 #终端可以设置成没点一个按键变化一次,或者每次点回车编译一次 if chan in readable: try: x = chan.recv(1024) #x = u(chan.recv(1024)) 然后这里把u用上了 if len(x) == 0: print('\r\n*** EOF\r\n') break sys.stdout.write(x.decode()) #往屏幕上写 sys.stdout.flush() #刷新,显示出来 except socket.timeout: pass if sys.stdin in readable: inp = sys.stdin.readline() #读取数据的值 chan.sendall(inp) #利用chan将数据发送出去 chan.close() tran.close()
上面的方式是按一下回车发送以下,不支持tab不全,所以我们要把每次按键,按一次发送一次。

#!/usr/bin/env python3 # Created by han on 2016/8/4 import paramiko import sys import os import socket import select import getpass import paramiko import sys import os import socket import select import getpass import termios import tty from paramiko.py3compat import u tran = paramiko.Transport(('192.168.109.134', 22,)) tran.start_client() tran.auth_password('han', '123456') # 打开一个通道 chan = tran.open_session() # 获取一个终端 chan.get_pty() # 激活器 chan.invoke_shell() # 获取原tty属性 oldtty = termios.tcgetattr(sys.stdin) #原程序:每一个回车发送一个 try: # 为tty设置新属性 # 默认当前tty设备属性: # 输入一行回车,执行 # CTRL+C 进程退出,遇到特殊字符,特殊处理。 # 这是为原始模式,不认识所有特殊符号 # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器 tty.setraw(sys.stdin.fileno()) #修改终端状态 chan.settimeout(0.0) while True: # 监视 用户输入 和 远程服务器返回数据(socket) # 阻塞,直到句柄可读 r, w, e = select.select([chan, sys.stdin], [], [], 1) if chan in r: try: x = u(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) chan.close() tran.close()
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· “你见过凌晨四点的洛杉矶吗?”--《我们为什么要睡觉》
· 编程神器Trae:当我用上后,才知道自己的创造力被低估了多少
· C# 从零开始使用Layui.Wpf库开发WPF客户端
· C#/.NET/.NET Core技术前沿周刊 | 第 31 期(2025年3.17-3.23)
· 接口重试的7种常用方案!