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

环境准备
在开始之前,需要确保本地Python环境已安装必要的库。paramiko
是一个纯Python实现的SSHv2协议库,而fabric
则基于paramiko
提供了更高层次的抽象,可以通过pip安装这两个库:
pip install paramiko pip install fabric
使用paramiko实现SSH远程执行命令
paramiko
提供了直接操作SSH连接的底层接口,适合需要精细控制的场景,以下是基本步骤:
-
建立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')
-
执行命令:通过
exec_command()
方法执行远程命令,该方法返回三个对象:标准输入、标准输出和标准错误。(图片来源网络,侵删)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)
-
关闭连接:操作完成后,使用
close()
方法关闭SSH连接。ssh.close()
使用fabric实现SSH远程执行命令
fabric
提供了更简洁的API,适合快速编写自动化脚本,以下是基本步骤:
-
定义连接信息:使用
env
字典配置远程服务器的连接参数。from fabric import Connection c = Connection(host='192.168.1.100', user='root', connect_kwargs={'password': 'password'})
-
执行命令:通过
run()
方法执行远程命令,fabric
会自动处理输出和错误。(图片来源网络,侵删)result = c.run('ls -l') print("Exit status:", result.return_code) print("Output:", result.stdout)
-
关闭连接:
fabric
的连接对象支持上下文管理器,可以自动关闭连接。with Connection(host='192.168.1.100', user='root', connect_kwargs={'password': 'password'}) as c: c.run('ls -l')
高级功能
-
文件传输:
paramiko
和fabric
都支持文件传输功能。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')
-
交互式命令:对于需要交互的命令(如
sudo
),可以使用paramiko
的invoke_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)
-
多线程执行:对于需要同时操作多台服务器的场景,可以使用
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())
常见问题与解决方案
-
SSH连接超时:可能是网络问题或服务器配置限制,可以通过设置
timeout
参数调整连接超时时间。ssh.connect(hostname='192.168.1.100', timeout=10)
-
密钥认证失败:确保本地私钥文件路径正确,并设置正确的权限(通常为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: 可以使用paramiko
的invoke_shell()
方法或fabric
的run()
方法结合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')