【问题标题】:How to execute code after a spawned, detached, child exits from NodeJS如何在生成、分离的子节点从 NodeJS 退出后执行代码
【发布时间】:2017-06-16 05:13:07
【问题描述】:

我的目标是在从 NodeJS 应用程序生成一个分离的、未引用的子进程后执行一些代码。这是我的代码:

var child_options = {
      cwd : prj
    , env : {
                PATH: cmd_directory
            }
    , detatched : true
    , stdio     : 'ignore'
};

//Spawn a child process with myapp with the options and command line params
child = spawn('myapp', params_array, child_options, function(err, stdout, stderr){

    if (err) {
        console.log("\t\tProblem executing myapp =>\n\t\t" + err);
    } else {
        console.log("\t\tLaunched myapp successfully!")
    }

});

//Handle the child processes exiting.  Maybe send an email?
child.on('exit', function(data) {

    fs.writeFile(path.resolve("/Users/me/Desktop/myapp-child.log"), "Finished with child process!");

});

//Let the child process run in its own session without parent
child.unref();

因此,当子进程完成时,exit 处理程序中的函数似乎没有被执行。有什么办法可以在子进程退出后执行代码,即使它已分离并且在调用.unref() 方法时也是如此?

请注意,如果我将child_options 对象中的'stdio' 键值从'ignore' 更改为'inherit',则exit 处理程序会执行。

有什么想法吗?



更新第 1 部分


所以,我仍然无法弄清楚这一点。我回到 spawn 上的 NodeJS 文档,并注意到有关生成“长时间运行的进程”的示例。在一个示例中,他们将子进程的输出重定向到文件,而不是仅使用 'ignore' 来设置 'stdio' 选项。所以我更改了child_options 对象中的'stdio' 键,如下所示,但是我仍然无法执行'close''exit' 事件中的代码:

var out_log = fs.openSync(path.resolve(os.tmpdir(), "stdout.log"), 'a'),
    err_log = fs.openSync(path.resolve(os.tmpdir(), "stderr.log"), 'a');

var child_options = {
      cwd : prj
    , env : {
                PATH: cmd_directory
            }
    , detatched : true
    , stdio     : ['ignore', out_log, err_log]
};

所以,stdout.log 文件确实从子进程中获取了标准输出——所以我知道它会被重定向。但是,closeexit 事件中的代码仍然没有执行。然后我想我可以检测到对out_log 文件的写入何时完成,在这种情况下我可以在那个时候执行代码。但是,我无法弄清楚如何做到这一点。有什么建议吗?

【问题讨论】:

    标签: node.js child-process


    【解决方案1】:

    您可以将侦听器添加到“关闭”事件,例如将“退出”替换为“关闭”。即使使用“忽略”stdio,它也对我有用。另外,回调中的输入参数是退出代码号或null。

    根据nodejs文档的exit和close事件的区别:

    'close' 事件在子进程的 stdio 流时触发 已关闭。这与“退出”事件不同,因为 多个进程可能共享相同的 stdio 流。

    希望对你有帮助。

    【讨论】:

    • 我将其更改为'close',但将日志文件写入我的桌面仍然没有运气。我认为这可能与写入桌面的某些权限问题有关,但我对此表示怀疑,因为如果我将'inherit' 用于子进程,则文件确实会写入桌面。关于你关于“输入参数”的说法,你指的是data参数吗?我会尝试删除它。
    • 是的,我的意思是data 参数,但这并不重要,请注意。您是否检查过,如果您传递“忽略”参数,该过程就会启动?我有类似的情况,问题在于子进程等待输入流,而子进程没有做任何事情。
    • 我确定,通过检查 macOS 上的“活动监视器”应用程序,子进程确实会在我使用 'stdio' 键的 'ignore' 值时启动。我不知所措。有什么想法吗?
    • 抱歉回复晚了。我的陈述不清楚。我的意思是,当进程启动时(在我的情况下是 Web 服务器),我遇到了这种情况,但它没有监听端口,所以我无法发送任何查询。我认为,原因是等待启动的网络服务器从标准输入输入。我删除了 Web 服务器中的处理输入,所有这些都神奇地使用了 'stdio' 键的 'ignore' 值。请澄清一下,是否使用“stdio”的“忽略”值触发了“退出”事件的回调?
    • 我正在启动的子进程不是 Web 服务器。它对文件进行一些转码,然后完成。不过,似乎我调用的启动自身的命令会产生另一个进程。会不会是这个问题?
    猜你喜欢
    • 2016-06-16
    • 2011-08-11
    • 2020-10-18
    • 2023-03-06
    • 1970-01-01
    • 2012-10-07
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多