如何通过SSH远程执行Python程序并建立TCP客户端-服务器连接
解决SSH远程执行Python程序及TCP服务端监听的问题
我来帮你搞定这两个场景的问题——你之前用exec_command遇到异常,大概率是因为SSH默认的命令执行通道会在命令"完成"后关闭,没法持续维持交互式通信,或者服务端进程跟着SSH会话一起终止了。下面给你分场景提供可行方案:
场景一:SSH远程执行Python程序并保持实时通信数分钟
exec_command是非交互式的,没法持续和远程程序双向通信,这里推荐用paramiko的invoke_shell创建交互式会话,它能保持SSH连接的持续性,支持实时收发数据。
示例代码:
import paramiko import time # 建立SSH连接 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect("远程主机IP/域名", username="你的用户名", password="你的密码") # 打开交互式shell通道 shell = ssh.invoke_shell() # 发送启动Python程序的命令(如果需要sudo,后面会说处理方式) shell.send("python your_interactive_program.py\n") # 持续监听通信5分钟(300秒) start_time = time.time() while time.time() - start_time < 300: # 读取远程程序的输出 if shell.recv_ready(): output = shell.recv(1024).decode("utf-8") print(f"远程程序输出:{output}") # 给远程程序发送输入(如果需要的话) # shell.send("your_input_text\n") time.sleep(0.5) ssh.close()
如果你的程序需要sudo权限,直接用invoke_shell发送密码即可(更安全的方式是修改sudoers免密,后面场景二会提):
shell.send("sudo python your_interactive_program.py\n") time.sleep(1) # 等待sudo提示输入密码 shell.send("你的sudo密码\n")
场景二:远程启动TCP服务端并保持监听,本地客户端连接
这里的核心是让远程服务端进程脱离SSH会话运行,不然SSH连接关闭后服务端会被终止。推荐两种方案:
方案1:用nohup让服务端后台持久运行
nohup会让程序忽略SSH会话关闭时的HUP信号,同时重定向输出避免占用终端。
示例代码:
import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect("远程主机IP/域名", username="你的用户名", password="你的密码") # 用nohup启动服务端,后台运行,输出写入nohup.out # 如果需要sudo,同样可以结合密码输入或免密配置 command = "sudo nohup python server.py > nohup.out 2>&1 &" stdin, stdout, stderr = ssh.exec_command(command) # 等待命令执行完成(确保服务端启动) stdout.channel.recv_exit_status() # 关闭SSH连接,服务端会继续在后台监听 ssh.close() # 现在本地运行客户端程序即可连接 # 本地client.py示例: # import socket # client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # client.connect(("远程主机IP/域名", 你的服务端端口)) # 后续进行数据交互
方案2:用screen/tmux创建持久化会话(更便于后续管理)
如果需要后续查看服务端输出或重启服务,用screen或tmux更灵活,它们能创建脱离SSH会话的终端环境。
示例代码:
import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect("远程主机IP/域名", username="你的用户名", password="你的密码") # 创建名为tcp_server的screen会话,后台启动服务端 command = "sudo screen -dmS tcp_server python server.py" stdin, stdout, stderr = ssh.exec_command(command) stdout.channel.recv_exit_status() ssh.close() # 后续如果需要查看服务端输出,重新SSH连接后执行: # screen -r tcp_server
关于sudo权限的优化建议
硬编码密码不安全,你可以在远程机器上修改sudoers文件,让你的用户免密执行Python命令:
- 远程执行
sudo visudo - 添加一行:
你的用户名 ALL=(ALL) NOPASSWD: /usr/bin/python(根据实际Python路径调整,可用which python查询)
这样后续执行sudo python就不需要输入密码了。
内容的提问来源于stack exchange,提问作者Rahul Nimbal
相关产品推荐
相关产品推荐

