【问题标题】:Prevent sending data to stdin if spawn fails如果生成失败,防止将数据发送到标准输入
【发布时间】:2023-12-26 23:56:01
【问题描述】:

在我的 Node.js (v0.10.9) 代码中,我试图检测 2 种情况:

  • 安装了一个外部工具 (dot) - 在这种情况下,我想将一些数据发送到已创建进程的标准输入
  • 未安装外部工具 - 在这种情况下,我想显示警告并且我不想发送任何东西来处理“标准输入”

我的问题是,当且仅当进程成功生成(即标准输入已准备好写入)时,我不知道如何将数据发送到孩子的标准输入。 如果安装了 dot,则以下代码可以正常工作,否则它会尝试将数据发送给孩子,尽管孩子没有产生。

var childProcess = require('child_process');

var child = childProcess.spawn('dot');
child.on('error', function (err) {
  console.error('Failed to start child process: ' + err.message);
});
child.stdin.on('error', function(err) {
  console.error('Working with child.stdin failed: ' + err.message);
});

// I want to execute following lines only if child process was spawned correctly
child.stdin.write('data');
child.stdin.end();

我需要这样的东西

child.on('successful_spawn', function () {
  child.stdin.write('data');
  child.stdin.end();
});

【问题讨论】:

    标签: node.js stdin spawn


    【解决方案1】:

    来自 node.js 文档:http://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options

    检查失败的执行示例:

    var spawn = require('child_process').spawn,
        child = spawn('bad_command');
    
    child.stderr.setEncoding('utf8');
    child.stderr.on('data', function (data) {
      if (/^execvp\(\)/.test(data)) {
        console.log('Failed to start child process.');
      }
    });
    

    【讨论】:

    • 我尝试了这段代码,它根本没有检测到失败的生成,但是这个问题已经解决了here。检测不是我的问题,如果产卵失败,我想阻止父母向孩子发送数据。
    • 好吧,你提到的链接说当出现错误时会发出错误事件。我假设也会发出成功事件,那么呢?在那里运行你的标准输入管道逻辑。
    • 通过documentation,ChildProcess 发出以下事件:错误、退出、关闭、断开连接和消息。似乎没有一个是正确的。
    【解决方案2】:

    看看 core-worker: https://www.npmjs.com/package/core-worker

    这个包使处理流程变得更加容易。 我认为您想要做的是类似的事情(来自文档):

    import { process } from "core-worker";
    
    const simpleChat = process("node chat.js", "Chat ready");
    
    setTimeout(() => simpleChat.kill(), 360000); // wait an hour and close the chat
    
    simpleChat.ready(500)
        .then(console.log.bind(console, "You are now able to send messages."))
        .then(::simpleChat.death)
        .then(console.log.bind(console, "Chat closed"))
        .catch(() => /* handle err */);
    

    因此,如果进程没有正确启动,则不会执行任何 .then 语句,这正是您想要做的,对吧?

    【讨论】: