运行 Python 程序,并让其在脚本终止后继续运行

2025-02-11 09:51:00
admin
原创
95
摘要:问题描述:我尝试过运行这样的事情:subprocess.Popen(['nohup', 'my_command'], stdout=open('/dev/null', 'w'), stderr=open('logfile.log', 'a')...

问题描述:

我尝试过运行这样的事情:

subprocess.Popen(['nohup', 'my_command'],
                 stdout=open('/dev/null', 'w'),
                 stderr=open('logfile.log', 'a'))

如果父脚本正常退出,则此方法有效,但如果我终止脚本(Ctrl-C),则所有子进程也会被终止。有没有办法避免这种情况?

我关心的平台是 OS X 和 Linux,使用 Python 2.6Python 2.7。


解决方案 1:

子进程SIGINT与父进程接收相同的信息,因为它们位于同一个进程组中。您可以通过调用os.setpgrp()子进程将子进程放入其自己的进程组中。Popenpreexec_fn参数在这里很有用:

subprocess.Popen(['nohup', 'my_command'],
                 stdout=open('/dev/null', 'w'),
                 stderr=open('logfile.log', 'a'),
                 preexec_fn=os.setpgrp
                 )

preexec_fn仅适用于 un*x-oids。Windows 上似乎有一个大致相同的程序“ creationflags=CREATE_NEW_PROCESS_GROUP”,但我从来没试过。)

解决方案 2:

在 Unix 系统上,通常的做法是,如果您是父进程,则执行 fork 并退出。请查看os.fork()

下面是完成这个工作的函数:

def spawnDaemon(func):
    # do the UNIX double-fork magic, see Stevens' "Advanced 
    # Programming in the UNIX Environment" for details (ISBN 0201563177)
    try: 
        pid = os.fork() 
        if pid > 0:
            # parent process, return and keep running
            return
    except OSError, e:
        print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror) 
        sys.exit(1)

    os.setsid()

    # do second fork
    try: 
        pid = os.fork() 
        if pid > 0:
            # exit from second parent
            sys.exit(0) 
    except OSError, e: 
        print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror) 
        sys.exit(1)

    # do stuff
    func()

    # all done
    os._exit(os.EX_OK)

解决方案 3:

经过一个小时的各种尝试后,这对我来说是有效的:

process = subprocess.Popen(["someprocess"], creationflags=subprocess.DETACHED_PROCESS | subprocess.CREATE_NEW_PROCESS_GROUP)

这是适用于 Windows 的解决方案。

解决方案 4:

从 3.2 开始您还可以使用start_new_session标志(仅限 POSIX)。

import subprocess

p = subprocess.Popen(["sleep", "60"], start_new_session=True)
ret = p.wait()

参见Popen 构造函数中的 start_new_session

解决方案 5:

另一种方法是让子进程忽略SIGINT。

import subprocess
import signal
subprocess.Popen(["sleep", "100"], preexec_fn=lambda: signal.signal(signal.SIGINT, signal.SIG_IGN))

使用preexec_fn确保父进程的 SIGINT 处理程序不会被改变。(如果它被改变了,你需要像这样恢复它。)

当然,这只有在子进程不继续恢复信号处理程序时才会起作用。在以下情况下,如果子进程安装了信号处理程序,则子进程仍将被终止:

import subprocess
import signal
process=subprocess.Popen(["python", "-c", "import signal
import time
signal.signal(signal.SIGINT, signal.SIG_DFL)
while True: 
    print(1)
    time.sleep(1)"], preexec_fn=lambda: signal.signal(signal.SIGINT, signal.SIG_IGN))
process.wait()

感谢https://stackoverflow.com/a/3731948/5267751

解决方案 6:

with open('/dev/null', 'w') as stdout, open('logfile.log', 'a') as stderr:
    subprocess.Popen(['my', 'command'], stdout=stdout, stderr=stderr)

类子进程.Popen(...)

在新进程中执行子程序。在 POSIX 上,该类使用类似 os.execvp() 的行为来执行子程序。在 Windows 上,该类使用 Windows CreateProcess() 函数。

os.execvpe(文件,参数,环境)

这些函数都会执行一个新程序,替换当前进程;它们不会返回。在 Unix 上,新的可执行文件将加载到当前进程中,并且将具有与调用者相同的进程 ID。错误将报告为 OSError 异常。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用