Python通过Paramiko在Windows下远程连接Linux执行命令及状态获取
本文介绍如何使用Python的Paramiko库在Windows环境下远程连接Linux服务器并执行命令。重点解决多条命令顺序执行失效及非瞬时命令输出获取延迟的问题,通过利用channel的exit_status_ready()方法判断执行状态,确保命令完整执行并准确获取控制台输出。
前言
近期开发了一个小工具,旨在协助协作部门获取服务器上的资源信息。由于该工具基于PyQt开发,涉及Python远程连接Linux的技术实现,在此记录过程中遇到的相关问题及解决方案。
环境
工具
- PyCharm
- Qt Designer
库
- Python 3.7
- PyQt5.15.4
- Paramiko 2.12.0
经网络检索,Paramiko作为Python第三方库,实现远程SSH连接十分便捷,且安装过程简单。
pip install paramiko内容汇总
创建SSHClient
ssh = paramiko.SSHClient()首先,通过Paramiko实例化SSHClient类,该类封装了SSH链接建立及命令发送等核心功能。
设置链接主机后的策略
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())需配置连接未知主机密钥时的策略。通常有三种选项,一般直接使用Auto策略,系统会自动将远程主机的密钥添加至known_hosts文件中。
链接远程主机
ssh.connect(ip, port, username, password)- ip:指定远程主机的IP地址
- port:指定端口,默认为22
- username:指定访问主机的用户名
- password:指定访问主机的用户密码
调用connect方法建立连接。
发送命令
cmd = "python /work/tools/build_project.py"
stdin, stdout, stderr = ssh.exec_command(cmd)- stdin:用于输入交互内容
- stdout:获取命令在Linux控制台的正常输出内容
- stderr:获取命令执行失败时的错误信息
连接成功后,通过exec_command方法向主机发送命令,该方法返回三个参数。
获取linux的输出内容
stdin, stdout, stderr = ssh.exec_command(cmd)
successResult = stdout.read()
errorResult = stdout.read()可通过read方法读取Linux控制台的输出信息。
问题总结
在实际应用中遇到以下主要问题:
- 顺序执行多条命令时,后续命令往往不生效。
- 对于非瞬时完成的命令,read方法在第一时间无法获取到输出信息。
这两个问题在实际运行中会导致显著影响,例如以下场景:
cd /work
git pull
cd tools
python test.py当同时执行多条命令时,若其中包含git pull这类非瞬时完成的命令,后续命令将无法生效,且read方法无法获取控制台信息。起初尝试通过time.sleep(1)延时调用解决,但这种方式不够优雅且因执行时间不固定而缺乏可靠性。
解决方式
经搜索查找,发现exec_command返回的stdout参数中包含一个channel类。该channel可用于接收远端主机的执行状态,具体通过exit_status_ready()方法判断。当远端主机命令执行结束时,该方法返回true,从而便于后续处理。
stdin, stdout, stderr = ssh.exec_command(s_cmd, get_pty=True)
result = ""
while not stdout.channel.exit_status_ready():
result = result + stdout.readline()
if stdout.channel.exit_status_ready():
break如上述代码所示,在发送命令后,通过while循环持续判断远端主机的执行状态。当执行状态结束标志为真时,返回所有接收到的信息。
演示
以下为完整代码演示。为方便执行多条命令,此处直接调用shell脚本。
#!/bin/bash
project_path="/works"
cd $project_path
# 清理
git clean -f
git checkout *
# 拉代码
git pull
cd tools
python build_android.pyimport paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.x.xxx', 22, "root", 123456)
s_cmd = "sh /work/tools/ssh/build_android.sh"
stdin, stdout, stderr = ssh.exec_command(s_cmd, get_pty=True)
result = ""
while not stdout.channel.exit_status_ready():
result = result + stdout.readline()
if stdout.channel.exit_status_ready():
break
print(result)如上述代码所示,通过两个脚本的配合,即可实现多命令的远程调用及回执。另外建议将SSH操作置于子线程中处理,以避免阻塞主线程。
推送
Github
https://github.com/KingSun5
到此这篇关于Python在Windows下链接Linux执行命令并获取执行状态的文章就介绍到这了,更多相关Python执行Linux命令内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









