菜鸟科技网

Python如何SSH远程执行命令?

Python通过SSH远程执行命令是自动化运维、服务器管理和分布式系统中常见的操作,Python提供了多种库来实现SSH连接,其中最常用的是paramikofabric,本文将详细介绍如何使用这些库进行SSH远程执行命令,包括环境准备、基本用法、高级功能以及常见问题的解决方案。

Python如何SSH远程执行命令?-图1
(图片来源网络,侵删)

环境准备

在开始之前,需要确保本地Python环境已安装必要的库。paramiko是一个纯Python实现的SSHv2协议库,而fabric则基于paramiko提供了更高层次的抽象,可以通过pip安装这两个库:

pip install paramiko
pip install fabric

使用paramiko实现SSH远程执行命令

paramiko提供了直接操作SSH连接的底层接口,适合需要精细控制的场景,以下是基本步骤:

  1. 建立SSH连接:使用paramiko.SSHClient()创建SSH客户端对象,并通过connect()方法连接到远程服务器,需要指定主机名、端口、用户名和密码(或密钥)。

    import paramiko
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())  # 自动添加主机密钥
    ssh.connect(hostname='192.168.1.100', port=22, username='root', password='password')
  2. 执行命令:通过exec_command()方法执行远程命令,该方法返回三个对象:标准输入、标准输出和标准错误。

    Python如何SSH远程执行命令?-图2
    (图片来源网络,侵删)
    stdin, stdout, stderr = ssh.exec_command('ls -l')
    output = stdout.read().decode('utf-8')
    error = stderr.read().decode('utf-8')
    if error:
        print("Error:", error)
    else:
        print("Output:", output)
  3. 关闭连接:操作完成后,使用close()方法关闭SSH连接。

    ssh.close()

使用fabric实现SSH远程执行命令

fabric提供了更简洁的API,适合快速编写自动化脚本,以下是基本步骤:

  1. 定义连接信息:使用env字典配置远程服务器的连接参数。

    from fabric import Connection
    c = Connection(host='192.168.1.100', user='root', connect_kwargs={'password': 'password'})
  2. 执行命令:通过run()方法执行远程命令,fabric会自动处理输出和错误。

    Python如何SSH远程执行命令?-图3
    (图片来源网络,侵删)
    result = c.run('ls -l')
    print("Exit status:", result.return_code)
    print("Output:", result.stdout)
  3. 关闭连接fabric的连接对象支持上下文管理器,可以自动关闭连接。

    with Connection(host='192.168.1.100', user='root', connect_kwargs={'password': 'password'}) as c:
        c.run('ls -l')

高级功能

  1. 文件传输paramikofabric都支持文件传输功能。paramiko使用SFTPClient,而fabric使用put()get()方法。

    # paramiko文件上传
    sftp = ssh.open_sftp()
    sftp.put('local_file.txt', '/remote/path/file.txt')
    sftp.close()
    # fabric文件上传
    c.put('local_file.txt', '/remote/path/file.txt')
  2. 交互式命令:对于需要交互的命令(如sudo),可以使用paramikoinvoke_shell()方法。

    channel = ssh.invoke_shell()
    channel.send('sudo ls -l\n')
    channel.send('password\n')  # 输入sudo密码
    output = channel.recv(4096).decode('utf-8')
    print(output)
  3. 多线程执行:对于需要同时操作多台服务器的场景,可以使用concurrent.futures实现多线程SSH连接。

    import concurrent.futures
    def execute_command(host, command):
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(host, username='root', password='password')
        stdin, stdout, stderr = ssh.exec_command(command)
        output = stdout.read().decode('utf-8')
        ssh.close()
        return output
    hosts = ['192.168.1.100', '192.168.1.101']
    command = 'ls -l'
    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = [executor.submit(execute_command, host, command) for host in hosts]
        for future in concurrent.futures.as_completed(futures):
            print(future.result())

常见问题与解决方案

  1. SSH连接超时:可能是网络问题或服务器配置限制,可以通过设置timeout参数调整连接超时时间。

    ssh.connect(hostname='192.168.1.100', timeout=10)
  2. 密钥认证失败:确保本地私钥文件路径正确,并设置正确的权限(通常为600),可以使用paramiko.RSAKey.from_private_key_file()加载私钥。

    private_key = paramiko.RSAKey.from_private_key_file('/path/to/private_key')
    ssh.connect(hostname='192.168.1.100', username='root', pkey=private_key)

相关问答FAQs

Q1: 如何在Python中通过SSH执行远程命令并获取实时输出?
A: 可以使用paramikoinvoke_shell()方法或fabricrun()方法结合pty=True参数实现实时输出。

# paramiko实时输出
channel = ssh.invoke_shell()
channel.send('command\n')
while True:
    if channel.recv_ready():
        print(channel.recv(1024).decode('utf-8'))

Q2: 如何处理SSH连接中的主机密钥验证问题?
A: 主机密钥验证是为了防止中间人攻击,可以通过paramiko.AutoAddPolicy()自动添加主机密钥(不推荐生产环境),或手动将服务器的主机密钥添加到known_hosts文件中:

# 手动添加主机密钥
ssh.load_system_host_keys()
ssh.connect(hostname='192.168.1.100', key_filename='/path/to/private_key')
分享:
扫描分享到社交APP
上一篇
下一篇