【问题标题】:Process started with nohup is not detached from parent以 nohup 启动的进程未与父进程分离
【发布时间】:2017-03-05 12:21:44
【问题描述】:

我有以下简化脚本:

Pythontest.py:

import subprocess, os


def run_background_process(script_name):
    with open(os.devnull, 'w') as FNULL:
        background_process = subprocess.Popen(['nohup', '{}'.format(script_name)], stdout=FNULL
                     , stderr=FNULL
                     , stdin=FNULL)

    return background_process

while True:
    run_background_process('test.sh')
    time.sleep(500)

Bash shell 脚本test.sh:

#!/bin/bash

n=1

echo ${n}
sleep 30

ps -ef 结果是:

15536 16555  0 14:18 test.py
15541 15536  0 14:18 test.sh

所以我的问题是,为什么test.sh 没有与test.py 分离,它仍然是test.py 的孩子?

【问题讨论】:

    标签: python linux bash shell subprocess


    【解决方案1】:

    除非父进程终止,否则每个子进程仍然是其原始父进程的子进程。如果发生这种情况,PID 为 1 的进程将成为孤儿的新父进程。

    使用nohup 不会破坏这种关系。 (为此,孩子必须fork 一个新进程并终止自己,但这是另一个话题)。所以第一个答案是肯定的,孩子仍然是其父母的孩子。

    很难直接回答另一个问题。您的问题中“分离”的含义不是很明确。我确实建议查看一些关于 Unix/Linux 中的进程组(进程集合)、作业控制、控制终端和会话(进程组集合)的教程。

    nohup 实用程序的目的是保护已启动的进程在您注销时不被终止。退出的 shell 执行清理并将SIGHUP 信号发送到其控制下的所有进程。此外,正在使用的终端设备(键盘输入、屏幕输出)将在注销期间关闭。 nohup 只是确保忽略 SIGHUP 并且不使用终端。因此,相应的进程可以在注销后继续工作。

    【讨论】:

    • 我的意思是,我希望孩子在父母被杀时继续执行。在上面的情况下不会发生这种情况,如果我们在 child 中放置一个永久循环,它仍然会在 parent 被杀死时终止。
    • @CuriousGuy 是不是,你正在用 ctrl-C 杀死父母?
    • 是的,现在我意识到这是问题所在……只有父母正常退出,孩子才会活着,对吧?
    • @CuriousGuy ctrl-C 被发送到进程组中的所有进程,这包括子进程。它被 Ctrl-C 杀死。
    • @CuriousGuy 很高兴能帮上忙。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-19
    • 2012-05-05
    • 2012-09-20
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 2020-04-26
    相关资源
    最近更新 更多