在日常运维过程中,经常会遇见需要在不同的主机上批量执行某些复杂操作的需求,如果单纯的使用bash、expect等工具来写脚本,不仅脚本编写的难度大,功能实现复杂或者是无法实现,同时脚本的可阅读性和可维护性也很难维持在一个合理的水平,这时就需要采用一些更加现代和高效的方式。
Paramiko 是一个用于实现 SSH 协议的 Python 库,它提供了一种简单而强大的方式来执行远程命令、传输文件和管理 SSH 会话。本文将介绍如何使用 Paramiko 在 Python 中进行 SSH 操作。
在开始之前,我们需要先安装 Paramiko。在确保Python 环境可以访问互联网的条件下,可以使用 pip 包管理器在命令行中运行以下命令来安装 Paramiko:
pip install paramiko
2.1 连接到远程主机
1. #导入paramiko包
2. import paramiko
3.
4. # SSH 连接参数
5. host = "your_host"
6. username = "your_username"
7. password = "your_password"
8.
9. # 创建 SSH 客户端
10. ssh = paramiko.SSHClient()
11.
12. # 自动添加远程主机的 SSH 密钥
13. ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
14.
15. # 连接到远程主机
16. ssh.connect(host, username=username, password=password)
17.
18. # 关闭 SSH 连接
19. ssh.close()
2.2 执行远程命令
1. # 创建 SSH 客户端
2. ssh = paramiko.SSHClient()
3.
4. # 连接到远程主机
5. ssh.connect(host, username=username, password=password)
6.
7. # 执行远程命令
8. command = "ls -lrt"
9. stdin, stdout, stderr = ssh.exec_command(command)
10.
11. # 获取命令输出
12. output = stdout.read().decode("utf-8")
13.
14. # 关闭 SSH 连接
15. ssh.close()
2.3 传输文件
1. # 创建 SSH 客户端
2. ssh = paramiko.SSHClient()
3.
4. # 连接到远程主机
5. ssh.connect(host, username=username, password=password)
6.
7. # 本地文件路径和远程文件路径
8. local_path = "/path/to/local/file.txt"
9. remote_path = "/path/to/remote/file.txt"
10.
11. # 上传文件
12. sftp = ssh.open_sftp()
13. sftp.put(local_path, remote_path)
14. sftp.close()
15.
16. # 下载文件
17. sftp = ssh.open_sftp()
18. sftp.get(remote_path, local_path)
19. sftp.close()
20.
21. #关闭 SSH 连接
22. ssh.close()
在上述代码中,我们使用 `open_sftp` 方法打开一个 SFTP 会话,通过 `put` 方法将本地文件上传到远程主机,或者通过 `get` 方法从远程主机下载文件到本地。
通过上述简单的示例,我想大家一定都学会了如何在python中使用paramiko模块实现远程主机上的各种操作,但是大家在实践过程中一定会发现一个重要的问题,那就是在真实的运维任务中,很多操作实际上并不都是在单用户的条件下实现的,通常需要频繁切换用户同时执行多条命令,但是上述paramiko的各种操作并不能够实现用户的切换和运行环境、命令的连续交互。
3.1 交互式 shell
1. channel = ssh.invoke_shell()
3.2 执行多条命令并获取完整结果
1. channel.send('command1\n')
2. output = channel.recv(65535).decode()
3. print(output)
4.
5. channel.send('command2\n')
6. output = channel.recv(65535).decode()
7. print(output)
8.
9. channel.send('command3\n')
10. output = channel.recv(65535).decode()
11. print(output)
1. def send_command(channel, command):
2. channel.send(command + '\n')
3. time.sleep(1) # 设置适当的延迟时间以确保数据完整性
4.
5. def receive_output(channel):
6. output = ''
7. while not channel.recv_ready():
8. time.sleep(0.1)
9. while channel.recv_ready():
10. output += channel.recv(1024).decode()
11. time.sleep(0.1)
12. return output
13.
14. commands = ['command1', 'command2', 'command3']
15. for command in commands:
16. send_command(channel, command)
17. output = receive_output(channel)
18. print(output)
1. def send_command(channel, command):
2. channel.send(command + '\n')
3.
4. def receive_output(channel):
5. output = ''
6. while channel.recv_ready():
7. output += channel.recv(1024).decode()
8. return output
9.
10. commands = ['command1', 'command2', 'command3']
11. for command in commands:
12. send_command(channel, command)
13.
14. # 等待命令执行完毕
15. while not channel.exit_status_ready():
16. time.sleep(0.1)
17.
18. output = receive_output(channel)
19. print(output)
总 结:

本文作者:李双修(上海新炬中北团队)
本文来源:“IT那活儿”公众号

文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




