如何通过Python/Paramiko经SSH在树莓派上启动GUI应用并显示本地屏
问题描述
我用搭载HDMI显示屏的树莓派作为服务器,希望通过Windows 10电脑上的Python程序,借助Paramiko经SSH在树莓派上执行GUI应用,使其显示在树莓派的本地显示屏上。
在Windows控制台手动执行以下步骤可正常运行:
ssh -X user@raspberrypiexport DISPLAY=:0python3 my_gui_app.py
但使用以下Python脚本执行时无报错,却无法在树莓派屏幕弹出窗口:
import paramiko hostname = "raspberrypi" username = "user" password = "1234" command = "python3 my_gui_app.py" client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: client.connect(hostname=hostname, username=username, password=password) with client.get_transport().open_session() as session: session.get_pty() session.request_x11(single_connection=True) session.set_environment_variable("DISPLAY", ":0") session.exec_command(command) # Continuously read the stdout and stderr streams while True: if session.recv_ready(): stdout = str(session.recv(4096).decode("utf-8")) print(stdout, end="") if session.recv_stderr_ready(): stderr = str(session.recv_stderr(4096).decode("utf-8")) print(stderr, end="") # Check if the command has finished executing if session.exit_status_ready(): break finally: client.close()
请问我哪里操作有误?
问题分析与解决
你的脚本里有两个关键问题导致GUI窗口无法在树莓派本地显示:
- 多余的X11转发请求:你需要GUI显示在树莓派本地显示屏,
session.request_x11()是把树莓派的GUI窗口转发到Windows本地的X服务器,和需求完全冲突,直接删掉这一行即可。 - 环境变量设置不可靠:
session.set_environment_variable()在exec_command()前调用,对部分SSH服务器的环境变量生效支持有限。更稳妥的方式是把环境变量设置和执行命令合并成一条,直接在命令中指定DISPLAY:
同时删掉原来的command = "export DISPLAY=:0 && python3 my_gui_app.py"session.set_environment_variable("DISPLAY", ":0")行。
另外session.get_pty()可以保留,它模拟的终端环境能满足部分GUI应用的启动要求。
修改后的脚本如下:
import paramiko hostname = "raspberrypi" username = "user" password = "1234" # 合并环境变量设置与执行命令 command = "export DISPLAY=:0 && python3 my_gui_app.py" client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: client.connect(hostname=hostname, username=username, password=password) with client.get_transport().open_session() as session: session.get_pty() session.exec_command(command) # 持续读取输出流 while True: if session.recv_ready(): stdout = str(session.recv(4096).decode("utf-8")) print(stdout, end="") if session.recv_stderr_ready(): stderr = str(session.recv_stderr(4096).decode("utf-8")) print(stderr, end="") if session.exit_status_ready(): break finally: client.close()
内容的提问来源于Stack Exchange,提问作者Markus
相关产品推荐
相关产品推荐

