【问题标题】:Restart process via Bash通过 Bash 重启进程
【发布时间】:2014-09-30 12:51:25
【问题描述】:

我正在编写一个应该自行重启的 Python 脚本。

这就是我在 Python 脚本中所做的事情

os.execl('run.sh', '')

我的 run.sh 然后看起来像这样

#!/bin/bash
sudo fuser -ku 8000/tcp
python /home/app.py

我使用 sudo fuser -ku 8000/tcp 的原因是因为它很简单,因为我的 python 脚本是唯一使用端口 8000 的脚本。

当我运行 python 脚本时,它会执行此操作并停止。

8000/tcp:             7587(pi)  7596(pi)  7597(pi)  7605(pi)  7606(root)
./run.sh: line 3:  7587 Killed                  python /home/app.py

它永远不会重新启动 python 脚本。

【问题讨论】:

    标签: python bash


    【解决方案1】:

    根据os.execl() 文档,此函数会替换当前的 Python 进程,并且永远不会返回。所以你有这个:

    • Python 正在运行,调用 execl(run.sh),现在不再运行
    • run.sh 正在运行,出于某些不道德的原因使用 sudo(同一用户,可以在没有 sudo 的情况下终止!),尝试使用其端口号 (?!) 查找 Python 程序,然后终止它(或不终止,因为你根本不处理你的shell脚本中的错误)。
    • run.sh(如果在所有杀戮之后它还活着)尝试启动 Python 脚本。

    这是一种非常复杂的做事方式。相反,您应该简单地将 Python 进程替换为自身:

    os.execlp('python', '/home/app.py')
    

    对于奖励积分,您可以获取当前的 Python 和脚本(例如,使用 sys.argv)并使用它们而不是硬编码它们。有关详细信息,请参阅此处:Restarting a self-updating python script

    【讨论】:

    • 谢谢!你的解决方案把我带到了一半。它确实重新启动了 python 脚本,但我在脚本中运行的 Flask 服务器给了我这个错误:错误:[Errno 98] 地址已在使用中
    • 查找SO_REUSEADDR 来解决这个问题。
    • 我似乎无法为 Flask 找到类似的东西,是否会以某种方式公开 Flask 使用的套接字?
    【解决方案2】:

    当 python 代码执行时,它会创建sys.argv

    when Python is invoked, it sets sys.argv to everything but it's own executable.

    所以你需要使用os.execlp('python', 'the_directory')

    请参阅here 了解其工作的详细答案。

    【讨论】:

      【解决方案3】:

      这并不能完全回答您的问题,但是如果您想要实现的服务能够以零停机时间响应 TCP 请求并能够对其进行更新,那么唯一合适的解决方案是通过 UNIX 跨进程传递文件描述符插座。

      代码的骨架可能是这样的:

      • python 脚本启动并尝试绑定某个 unix 套接字。套接字的名称应以零字节开头,因为这将确保套接字在进程执行时终止。 (这被称为 Linux 抽象套接字命名空间)
        • 如果成功,则表示没有以前运行的服务器实例。将 TCP 服务器绑定到端口 8000 并接受连接并处理这些请求。在 UNIX 套接字上侦听下一个 python 实例的到来。当一个连接到那个 UNIX 套接字时,停止接受 TCP 服务器套接字上的传入连接,然后将该文件描述符传递给下一个实例,然后传递其他客户端的所有文件描述符(或者如果请求很快就完成处理它们)。然后死。
        • 如果失败,则表示之前有一个正在运行的实例。然后连接到它,打个招呼,通过它获取所有的文件描述符。第一个是 TCP 服务器套接字,所以开始接受新的连接。其他文件描述符是已经连接的客户端...

      使用该方法可以构建真正透明的服务器重启。 您需要一个额外的库来将文件描述符从一个进程传递到另一个进程,如下所示:http://code.google.com/p/python-passfd/

      【讨论】:

        猜你喜欢
        • 2017-08-04
        • 2018-06-14
        • 1970-01-01
        • 2010-11-25
        • 1970-01-01
        • 1970-01-01
        • 2013-10-20
        • 1970-01-01
        • 2021-01-12
        相关资源
        最近更新 更多