Python中paramiko模块的基础操作与排错问题

作者:程序员-小李 时间:2023-06-21 04:45:33 

关于

python的ssh库操作需要引入一个远程控制的模块——paramiko,可用于对远程服务器进行命令或文件操作。

应用

登陆服务器,问题排查。可用于编写脚本,在服务器上做一些繁琐的重复操作。

安装

打开cmd,输入命令python -m pip install paramiko

示例

1.秘钥登陆

配置免密登录,linux上信任了windows的公钥,然后脚本在windows上跑,使用windows的私钥就可以直接不要密码登录linux

注意:提供秘钥的paramiko.RSAKey.from_private_key_file('文件'),这里面的"文件"是你本机上的秘钥,不是指你被控机上的公钥哦!

import paramiko

key = paramiko.RSAKey.from_private_key_file("C:\\Users\\liyansheng\\.ssh\\id_rsa")
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print("connecting")
ssh.connect(hostname="192.168.220.128", username="root", pkey=key)
print("connected")
commands = "uname -a"
stdin, stdout, stderr = ssh.exec_command(commands)
stdin.close()
res, err = stdout.read(), stderr.read()
result = res if res else err
print(result)
ssh.close()

if __name__ == '__main__':
   print()

2.单个命令执行

1.创建一个.py文件,引入 paramiko模块

import paramiko

2.建立SSHClient对象

ssh = paramiko.SSHClient()

3.设置可信任,将主机加到host_allow列表

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

4.创建连接

ssh.connect("150.158.16.123", 22, "wuyanping", "2022")

5.创建命令,发送并获取响应结果

stdin, stdout, stderr = ssh.exec_command("ls /home")
   print(stdout.read().decode("utf-8"))

6.关闭连接

ssh.close()

3.执行多个命令

# 执行多条命令,注意传入的参数有个list
def execMultiCmd(host, user, psw, cmds: list, port=22) -> (str, str):
   with paramiko.SSHClient() as ssh_client:
       ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
       ssh_client.connect(hostname=host, port=port, username=user, password=psw)
       cmd = ";".join(cmds)
       _, stdout, stderr = ssh_client.exec_command(cmd, get_pty=True)
       result = stdout.read().decode('utf-8')
       err = stderr.read().decode('utf-8')
   return result, err

if __name__ == '__main__':
   cmdList = ["cd /home", "ls"]
   print(execMultiCmd("192.168.220.128", "root", "root", cmdList))

4.SFTPClient下载文件

方法封装:

def down_file(host, user, psw, local_file, remote_file, port=22):
   with paramiko.Transport((host, port)) as transport:
       # 连接服务
       transport.connect(username=user, password=psw)
       # 获取SFTP示例
       sftp = paramiko.SFTPClient.from_transport(transport)
       # 下载
       sftp.get(remote_file, local_file)
       transport.close()

问题:(错误)

if __name__ == '__main__':
   down_file(my_linux.host, my_linux.user, my_linux.psw, "D:\\ssh_download", "/home/test.txt")
Traceback (most recent call last):
 File "D:\MyCode2\py-1\ssh\download.py", line 17, in <module>
   down_file("192.168.220.128", "root", "root", "D:\\ssh_download", "/home/test.txt")
 File "D:\MyCode2\py-1\ssh\download.py", line 11, in down_file
   sftp.get(remote_file, local_file)
 File "D:\MyCode2\py-1\venv\lib\site-packages\paramiko\sftp_client.py", line 810, in get
   with open(localpath, "wb") as fl:
PermissionError: [Errno 13] Permission denied: 'D:\\ssh_download'

正确使用

要指定下载的文件名,不能只是一个目录

if __name__ == '__main__':
   down_file(my_linux.host, my_linux.user, my_linux.psw, "D:\\ssh_download\\test.txt", "/home/test.txt")

5.上传文件

def upload_file(host, user, psw, local_file, remote_file, port=22):
   with paramiko.Transport((host, port)) as transport:
       # 连接服务
       transport.connect(username=user, password=psw)
       # 获取SFTP示例
       sftp = paramiko.SFTPClient.from_transport(transport)
       sftp.put(local_file, remote_file)
       transport.close()

测试同下载,特别要注意路径问题。如

if __name__ == '__main__':
   upload_file(my_linux.host, my_linux.user, my_linux.psw, "D:\\ssh_download\\test123.txt", "/home/test/test123.txt")

6.ssh工具封装

import os

import paramiko

class SSHTool():
   def __init__(self, ip, port, user, psw):
       """
       初始化
       :param ip:
       :param port:
       :param user:
       :param psw:
       """
       self.ip = ip
       self.port = port
       self.user = user
       self.psw = psw

def connect_ssh(self):
       """
       创建连接
       :return:
       """
       try:
           self.ssh = paramiko.SSHClient()
           self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
           self.ssh.connect(
               hostname=self.ip,
               port=self.port,
               username=self.user,
               password=self.psw
           )
       except Exception as e:
           print(e)
       return self.ssh

def close_ssh(self):
       """
       关闭连接
       :return:
       """
       try:
           self.ssh.close()
       except Exception as e:
           print(e)

def exec_shell(self, shell):
       ssh = self.connect_ssh()
       try:
           stdin, stdout, stderr = ssh.exec_command(shell)
           return stdin, stdout, stderr
       except Exception as e:
           print(e)

def sftp_put_file(self, file, local_dir, remote_dir):
       try:
           t = paramiko.Transport((self.ip, self.port))
           t.connect(username=self.user, password=self.psw)
           sftp = paramiko.SFTPClient.from_transport(t)
           sftp.put(os.path.join(local_dir, file), remote_dir)
           t.close()
       except Exception:
           print("connect error!")

def sftp_get_file(self, file, local_dir, remote_dir):
       try:
           t = paramiko.Transport((self.ip, self.port))
           t.connect(username=self.user, password=self.psw)
           sftp = paramiko.SFTPClient.from_transport(t)
           sftp.get(remote_dir, os.path.join(local_dir, file))
           t.close()
       except Exception:
           print("connect error!")

补充

获取当前文件路径:os.getcwd()

import os

if __name__ == '__main__':
   print(os.getcwd())  # D:\MyCode2\py-1\ssh

python函数返回多个参数

def get_strs() -> (str, str):
   return "hello", "word"
if __name__ == '__main__':
   # 返回值为元祖的形式
   print(get_strs())  # ('hello', 'word')
   # 获取元祖的个数
   print(len(get_strs()))  # 2
   # 通过下标获取元祖的某一个值
   print(get_strs().__getitem__(1))  # word
   # 通过元祖的某个元素定位对应的下标
   print(get_strs().index("hello"))  # 0

with &hellip; as &hellip;使用

为了更好地避免此类问题,不同的编程语言都引入了不同的机制。在 Python 中,对应的解决方式是使用 with as 语句操作上下文管理器(context manager),它能够帮助我们自动分配并且释放资源。简单的理解,同时包含 enter() 和 exit() 方法的对象就是上下文管理器。

格式:

with 表达式 [as target]:
   代码块

学习参考

  • Python]远程SSH库Paramiko简介_alwaysrun的博客-CSDN博客_python ssh库

  • Python with as用法详解 (biancheng.net)

  • Python中的with-as用法 - 简书 (jianshu.com)

来源:https://blog.csdn.net/weixin_44107140/article/details/126729548

标签:Python,paramiko,模块
0
投稿

猜你喜欢

  • 原生js实现瀑布流效果

    2023-09-04 07:11:02
  • 从零开始学Golang的接口

    2023-10-09 02:26:03
  • 盘点30个经典常用的JavaScript知识点

    2024-05-13 09:36:06
  • Python中几种导入模块的方式总结

    2021-09-20 08:17:14
  • python偏函数的实例用法总结

    2021-06-05 03:42:13
  • python去除拼音声调字母,替换为字母的方法

    2022-02-13 10:43:55
  • Python安装Bs4的多种方法

    2023-08-07 07:35:04
  • 使用Spring Boot实现操作数据库的接口的过程

    2024-01-25 02:02:49
  • Python根据成绩分析系统浅析

    2023-08-02 20:25:07
  • asp三天学好ADO对象之第三天

    2008-10-09 12:53:00
  • Python下载网络文本数据到本地内存的四种实现方法示例

    2022-10-09 15:48:25
  • javascript适合移动端的日期时间拾取器

    2023-07-02 05:25:48
  • Mysql外键约束的创建与删除的使用

    2024-01-24 11:32:33
  • vue实际运用之vuex持久化详解

    2024-05-09 15:15:50
  • 如何处理Oracle中较大的文本数据?

    2009-11-11 20:06:00
  • Vue 2.0入门基础知识之内部指令详解

    2024-05-10 14:17:19
  • 第一篇初识bootstrap

    2024-04-28 09:41:01
  • JavaScript实现切换多张图片

    2024-04-17 09:54:18
  • PHP观察者模式原理与简单实现方法示例

    2024-05-03 15:49:15
  • python3调用百度翻译API实现实时翻译

    2021-06-21 01:45:46
  • asp之家 网络编程 m.aspxhome.com