You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask Python应用:如何执行远程脚本不等待POST响应?

解决Flask中远程执行无限循环脚本导致请求阻塞的问题

我明白你的困扰——当你在Flask的POST路由里执行那个带无限循环的远程脚本时,Python会一直等着ssh命令结束,但脚本永远不会终止,导致请求一直挂着。要解决这个问题,核心是让远程脚本在后台独立运行,同时让本地的Python进程不用等待命令完成。

下面是具体的实现方案:

关键思路

要达成两个核心目标:

  1. 让ssh命令立刻返回,不等待远程脚本执行完毕
  2. 确保远程脚本在ssh会话断开后依然能持续运行(避免ssh退出时杀掉脚本进程)

具体实现步骤

1. 用subprocess.Popen替代os.system

os.system会一直阻塞到命令执行完成,而subprocess.Popen是异步启动进程,调用后立刻返回,不会等待结果。这是解决本地请求阻塞的关键。

2. 让远程脚本脱离终端后台运行

在远程的ssh命令里,我们需要结合nohup和后台符号&,同时重定向输出,确保脚本不受ssh会话影响:

  • nohup:让脚本忽略挂起信号(SIGHUP),即使ssh连接关闭,脚本依然继续运行
  • > /dev/null 2>&1:把标准输出和错误输出重定向到空设备,避免占用远程机器的终端资源
  • &:让远程命令在后台执行,这样ssh会立刻完成并返回

3. Flask路由示例代码

from flask import Flask, request
import subprocess

app = Flask(__name__)

@app.route('/launch-script', methods=['POST'])
def launch_remote_script():
    # 构造远程执行的命令
    remote_cmd = "nohup /home/pi/script.sh > /dev/null 2>&1 &"
    # 用Popen异步执行ssh命令
    subprocess.Popen(
        ["ssh", "pizerow", remote_cmd],
        shell=False,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
    )
    # 立刻返回响应,不用等待脚本执行
    return "远程脚本启动请求已提交", 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

重要注意事项

  • 配置SSH免密登录:如果你的Flask运行用户还不能免密登录到pizerow,执行ssh命令时会弹出密码输入提示,导致请求再次阻塞。你需要生成SSH密钥对,并把公钥添加到pizerow的~/.ssh/authorized_keys文件中。
  • 给脚本加可执行权限:确保远程的script.sh有执行权限,执行chmod +x /home/pi/script.sh。
  • 可选:记录脚本日志:如果需要排查脚本运行情况,可以把输出重定向到日志文件,比如把命令改成nohup /home/pi/script.sh > /home/pi/script_run.log 2>&1 &,之后可以通过ssh查看这个日志文件。

为什么不用其他方法?

  • os.system:本质上会等待命令执行完成,无法异步处理。
  • subprocess.run/subprocess.call:同样是阻塞式调用,会一直等命令结束。
  • 仅加&而不用nohup:ssh会话关闭后,远程脚本会收到SIGHUP信号被终止,无法持续运行。

内容的提问来源于stack exchange,提问作者Bart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:19:23