【问题标题】:Run subprocess with several commands and detach to background keeping order使用多个命令运行子进程并分离到后台保持顺序
【发布时间】:2016-08-08 16:28:14
【问题描述】:

我正在使用subprocess 模块执行两个命令:

import shlex    
from subprocess import check_call()

def comm_1(error_file):
    comm = shlex("mkdir /tmp/kde")
    try:
        check_call(comm)
    except subprocess.CalledProcessError:
        error_file.write("Error comm_1")

def comm_2(error_file):
    comm = shlex("ls -la /tmp/kde")
    try:
        check_call(comm)
    except subprocess.CalledProcessError:
        error_file.write("Error comm_2")

if __name__ == "__main__":
    with open("error_file", "r+") as log_error_file:
         comm_1(log_error_file)
         comm_2(log_error_file)
         log_error_file.write("Success")

我知道此设计中存在一些缺陷,例如 error_file 与函数共享。不过,这很容易重构。我想要做的是将整个过程分离到后台。我会用

来完成这个
 check_call(comm, creationflags=subprocess.CREATE_NEW_CONSOLE)

但这会造成比赛问题,因为我想确保comm_1comm_2 开始之前完成。使用subprocess 执行此操作的最佳方法是什么?我不能使用python-daemon 或标准 Python 2.6 库之外的其他包。

编辑:我可以尝试使用类似的东西

nohup python myscript.py &

但想法是只有一种方法可以从 python 脚本开始工作。

【问题讨论】:

  • 似乎你可以改变一些事情,以便if __name__ == "__main__"myscript.py 产生了一些你目前正在做的事情 e 最后。使用正确的条件,这可能是本身
  • 对不起,我不听。我应该删除这些功能吗?

标签: python linux subprocess


【解决方案1】:

您可以使用wait() 在启动comm_2 中的子进程调用之前检查以确保comm_1 中的进程终止。但要这样做,您将不得不使用Popen() 而不是check_call()

from subprocess import Popen

def comm_1(error_file):
    comm = shlex("mkdir /tmp/kde")
    try:
        proc_1 = Popen(comm)
        proc_1.wait(timeout=20)
    except subprocess.CalledProcessError, TimeoutExpired:
        error_file.write("Error comm_1")

proc_1.wait() 将等待 20 秒(您可以更改时间)让该过程完成,然后再继续。如果花费的时间超过 20 秒,它将引发 TimeoutExpired 异常,您可以在 except 块中捕获该异常。

【讨论】:

  • 谢谢。使用Popenwait方法,会分离父进程吗?序列应该类似于start python process -> detach both functions -> comm_1 executes -> comm_2 executes,没有父进程仍然存在。
  • @Ivan 澄清一下,您的意思是当comm_1comm_2 继续在后台执行直到它们也完成之前,python 脚本是否会完全执行并完成?
  • 没错。 python 脚本是一个“启动器”,当comm_1comm_2 在后台运行时应该退出。
  • @Ivan 不幸的是没有。它会完全停止 python 进程并等待comm_1 子进程完成,然后再继续执行 python 脚本的其余部分。
  • @Ivan 我不完全确定这是否有效,但是如果您使用Popen(comm, close_fds=True),我相信python 进程会继续进行,而无需等待proc_1 完成,但是您可能会进入竞争条件与comm_2。喜欢的可以试试看。
猜你喜欢
  • 1970-01-01
  • 2010-12-10
  • 2013-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-28
相关资源
最近更新 更多