✨简介:

ssh是一个协议,OpenSSH是其中一个开源实现,paramiko是Python的一个库,实现了SSHv2协议(底层使用cryptography)。
有了Paramiko以后,我们就可以在Python代码中直接使用SSH协议对远程服务器执行操作,而不是通过ssh命令对远程服务器进行操作。

🌟安装Paramiko

首先,需要确保安装了Paramiko。可以使用pip来安装:

pip install paramiko

🌟Paramiko的主要类

SSHClient: 最常用的类,表示一个SSH客户端连接。
SFTPClient: 用于SFTP传输操作。
Transport: 低级别的模块,可用来实现SSH2协议。
SSHClient主要方法
connect(hostname, port=22, username=None, password=None, pkey=None): 用于连接到远程服务器。可以选择使用用户名和密码或密钥进行认证。
exec_command(command): 在远程服务器上执行指令。
open_sftp(): 返回一个SFTPClient对象,可用于文件的上传与下载。
SFTPClient主要方法
get(remotepath, localpath, callback=None): 下载远程文件。
put(localpath, remotepath, callback=None, confirm=True): 上传本地文件。
listdir(path=“.”): 列出远程目录的内容。

✨示例

🌟SSH连接并执行命令

import paramiko

# 创建SSH客户端
client = paramiko.SSHClient()

# 自动添加未知的服务器密钥及策略
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# 连接SSH服务端
client.connect('hostname', port=22, username='username', password='password')

# 执行命令
stdin, stdout, stderr = client.exec_command('ls -l')

# 获取命令执行结果
result = stdout.read()

print(result.decode())

# 关闭连接
client.close()

🌟通过SFTP上传和下载文件

import paramiko

# 创建SSH客户端
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('hostname', port=22, username='username', password='password')

# 创建SFTP会话
sftp = client.open_sftp()

# 上传文件
sftp.put('localfile.txt', '/remote/path/remote.txt')

# 下载文件
sftp.get('/remote/path/remote.txt', 'localfile.txt')

# 关闭SFTP会话和SSH连接
sftp.close()
client.close()

⚠️注意事项

在使用connect方法时务必考虑安全性,例如使用密钥认证而非明文密码。
对于错误处理,应当尝试捕获paramiko.ssh_exception.SSHException异常。
当不再需要SSH或SFTP客户端时,应当调用close()方法关闭连接。

🌟SSH方法的封装

下面提供一个比较简单的对SSH连接的封装的例子,实现了代理和不需要代理的方式连接服务器,以及发送命令,希望对大家有用。

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/5/9
# @Author  : Summer
# @File    : SSH
# @describe:
"""
import paramiko


class SSHClient:
    def __init__(self, hostname, port=22, username=None, password=None, pkey=None, use_proxy=False, proxy_hostname=None,
                 proxy_port=None, proxy_username=None, proxy_password=None, timeout=5):
        """
        初始化SSH客户端。

        :param hostname: 主机名或IP地址
        :param port: 端口号,默认是22
        :param username: 用户名
        :param password: 密码
        :param pkey: 私钥文件对象,用于密钥认证
        :param use_proxy: 是否使用代理标志
        :param proxy_hostname: 代理的主机名称
        :param proxy_port: 代理的端口号
        :param proxy_username: 代理的用户名
        :param proxy_password: 代理的密码
        """
        self.hostname = hostname
        self.port = port
        self.username = username
        self.password = password
        self.pkey = pkey
        self.use_proxy = use_proxy
        self.proxy_hostname = proxy_hostname
        self.proxy_port = proxy_port
        self.proxy_username = proxy_username
        self.proxy_password = proxy_password
        self.client = None
        self.timeout = timeout

    def _setup_proxy(self):
        """
        配置代理。
        """
        if self.use_proxy:
            proxy_ssh = paramiko.SSHClient()
            proxy_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            proxy_ssh.connect(hostname=self.proxy_hostname, port=self.proxy_port, username=self.proxy_username,
                              password=self.proxy_password, timeout=self.timeout)
            vm_transport = proxy_ssh.get_transport()
            remote_address = (self.hostname, self.port)
            local_address = (self.proxy_hostname, self.proxy_port)
            vm_channel = vm_transport.open_channel("direct-tcpip", remote_address, local_address)
            return vm_channel
        else:
            return None

    def _connect(self):
        """
        创建SSH连接。
        """
        self.client = paramiko.SSHClient()
        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        proxy = self._setup_proxy()
        self.client.connect(self.hostname, port=self.port, username=self.username, password=self.password,
                            pkey=self.pkey, sock=proxy, timeout=self.timeout)

    def exec_command(self, command):
        """
        在远程服务器上执行命令。
        :param command: 要执行的命令字符串
        :return: 命令输出结果的标准输出和标准错误
        """
        if self.client is None:
            self._connect()
        stdin, stdout, stderr = self.client.exec_command(command)
        return stdout.read().decode(), stderr.read().decode()

    def close(self):
        """
        关闭SSH连接。
        """
        if self.client:
            self.client.close()
            self.client = None


# 使用示例
if __name__ == "__main__":
    # 直接连接
    ssh = SSHClient(hostname='hostname', port=22, username='username', password='password')
    stdout, stderr = ssh.exec_command('ls -l')
    print(stdout)
    ssh.close()

    # 通过代理连接
    ssh_with_proxy = SSHClient(hostname='hostname', port=22, username='username', password='password', use_proxy=True,
                               proxy_hostname='proxy_hostname', proxy_port=22, proxy_username='proxy_username',
                               proxy_password='proxy_password')
    stdout, stderr = ssh_with_proxy.exec_command('ls -l')
    print(stdout)
    ssh_with_proxy.close()

✨paramiko和pexpect对比

Paramiko和pexpect都是Python库,用于与外部进程、系统和设备进行交互,但它们的设计目的和使用场景存在明显的区别。

🌟Paramiko

Paramiko是一个纯Python实现的SSHv2协议库,它提供了客户端和服务器的SSH功能。Paramiko使得用户可以很容易地使用Python进行安全的远程连接、文件传输(SFTP)以及端口转发。
主要特点
提供了SSH客户端和服务器端编程接口。
支持密钥认证和密码认证。
支持SFTP客户端和服务器功能。
可以用于创建SSH隧道。
提供了底层的通信传输接口(Transport)和高层的功能封装(SSHClient)。

🌟pexpect

pexpect是一个用于控制和自动化命令行应用程序的Python库。它能够启动子程序,并通过预设的期望模式与其交互,从而模拟用户的输入。这类似于在Unix和Linux系统中的脚本工具expect。
主要特点
通过预期模式匹配来交互,类似于Unix中的expect命令。
广泛用于自动构造与许多命令行应用程序的交互会话,不局限于SSH连接。
可以等待特定的字符串出现在输出中,然后发送字符串给进程。
通常用于执行自动化测试,如自动与命令行工具交互输入、输出。

🌟对比与优势

使用场景
Paramiko专注于SSH连接,适用于需要通过SSH执行命令、传输文件等脚本化的自动化任务。pexpect更为通用,可以用于自动化控制任何命令行交互,不仅限于SSH。

安全性
Paramiko直接支持SSH协议的加密和认证机制,非常适合执行需要加密和认证的远程操作任务。而pexpect本身并不处理加密或认证,但可以通过pexpect去调用使用SSH的命令,比如ssh。

复杂性
Paramiko为SSH操作提供了丰富的API,对于复杂的SSH交互和文件操作有着更好的支持。pexpect则在模拟用户和程序间简单交互上的使用更为直观。

平台兼容性
Paramiko是纯Python实现,无需依赖系统命令,因此跨平台支持较好。而pexpect原本设计用于Unix-like系统,虽然有为Windows平台提供的类似库(如winpexpect),但并非原生。

性能
Paramiko可能比pexpect在处理大量文件传输时更高效,因为它直接处理SSH协议。相比之下,pexpect在某些情况下可能因为依赖终端输出的文本匹配而效率较低。

根据具体使用场景来选择适合的工具是关键。如果任务主要涉及SSH连接,文件传输然后执行远程命令,Paramiko是更好的选择。如果目标是广泛的自动化控制各种命令行交互,而不仅仅是通过SSH,那么pexpect是更合适的选择。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐