【问题标题】:NodeJS child_process: close event not fired when specifying stdio: "inherit"NodeJS child_process:指定 stdio 时未触发关闭事件:\"inherit\"
【发布时间】:2023-02-07 10:57:25
【问题描述】:

我正在尝试使用 NodeJS 在 shell 中执行一些命令。因此我使用node:child_process 模块。

我使用 spawn 函数以便能够将子进程的输出转发到主进程的控制台。 为了保持子进程输出的格式,我传递了选项stdio: "inherit"(如本问题所述:preserve color when executing child_process.spawn)。

但是,如果我添加此选项,子进程事件(退出、断开连接、关闭...)将不再起作用。如果我去掉该选项,我将丢失格式,但事件有效。当子进程关闭时,有没有办法保持格式并得到通知?

(相关)代码:

const { spawn } = require("node:child_process");

let child = spawn("yarn", args, {
  stdio: "inherit",
  shell: true,
});
child.on("close", (code) => {
  console.log(`child process exited with code ${code}`);
});

【问题讨论】:

    标签: node.js child-process stdio


    【解决方案1】:

    stdio: 'inherit' 意味着您还将您的 STDIN 转发给子进程,因此如果子进程读取 STDIN,它将永远不会退出,并且您的 close 侦听器将永远不会被调用。特别是 Node.JS REPL (yarn node) 就是这种情况。

    根据您的需要,您可能想要:

    1. 只需使用child.kill() 停止子进程。然后调用close监听器,注意code为0,第二个参数(signal)为SIGTERMdocumentation);
    2. 不转发 STDIN 但仍转发 STDOUT 和 STDERR:调用 spawnstdio: ['ignore', 'inherit', 'inherit'] (documentation)。当子进程自行退出并释放流时,将调用close 侦听器。

    【讨论】:

    • 这些解决方案对我不起作用。我不能使用第一个,因为子进程需要完成,我不能就这样杀死它。如果我使用第二个关闭事件仍然不会被触发。
    • 然后请提供您正在使用的整个参数,以及一个模拟您正在启动的脚本的最小脚本(如果有的话)。可能是这个脚本有某种错误并且没有释放流,因此父进程永远不会触发 close 事件。
    • 我在上面脚本中的参数是:[ "create", "next-app", "test", "&&", "cd", "test", "&&", "yarn", "add", "styled- components”, “next-i18next”, “next-seo”, “&&”, “yarn”, “add”, “--dev”, “eslint-config-prettier”, “lint-staged”, “prettier” , "&&", "npx", "哈士奇初始化", ];
    • 哈,就是这个问题。您将所有这些参数都提供给单个进程 yarn,但 Yarn 不知道如何处理 && ...。你的意思是运行几个进程。因此,改为将每个步骤拆分为自己对 spawn 的调用,并通过回调或使用 Promises 将它们链接起来。
    猜你喜欢
    • 2016-04-30
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多