进程stdin,stdout和stderr重定向导致“读取ECONNRESET”

时间:2018-06-21 00:23:33

标签: node.js subprocess child-process io-redirection

我使用Node.Js child_process构建一个终端应用程序以运行其他进程。该应用程序需要执行其他可以交互的终端应用程序(子过程)。当我测试它时,大多数时候我会遇到read ECONNRESET,但是几次却能成功运行。

以下是我的代码中产生错误的一部分:

import {exec} from "child_process";
const command = "(echo 5 && echo 7) | python3 add.py 5 7";
// or: const command = "python3 add.py";
const subProcess = exec(command, options, (error, stdout, stderr) => {
  if (error) {
    return reject(error);
  }
  return resolve(stdout);
});

process.stdin.on("data", stdinListener);
subProcess.stdin.on("end", () => {
  process.stdin.removeListener("data", stdinListener);
  process.stdin.end();
});

subProcess.stdout.on("data", (chunk) => {
  process.stderr.write("\x1b[33m" + String(chunk) + "\x1b[0m");
});

subProcess.stderr.on("data", (chunk) => {
  process.stderr.write("\x1b[31m" + String(chunk) + "\x1b[0m");
});

function stdinListener(chunk) {
  subProcess.stdin.write(chunk);
}

基本上,我将on data侦听器应用于subProcess.stdoutsubProcess.stdin。因此,subProcess的每个输出也将在主进程中显示为stderr

我还将on data侦听器应用于process.stdin,因此用户可以使用process.stdin与子流程进行交互。

为简单起见,我放置了以下命令示例:(echo 5 && echo 7) | python3 add.py 5 7。我需要这样做是因为add.py可能带有参数(即python3 add.py 5 7)或以交互方式运行。用户甚至有可能只运行python3 add.py

这不是Web应用程序,只能在本地运行。因此,几乎没有安全威胁。

错误如下(并且并不总是显示):

Error: read ECONNRESET
    at _errnoException (util.js:992:11)
    at Pipe.onread (net.js:618:25)

这真令人沮丧,因为错误并非一直都发生。

我真的不知道怎么了。但我怀疑可能是这样:

  • 执行速度如此之快,甚至在subProcess重定向开始之前就已完成。
  • process.stdin可能不是停止subProcess的stdin的最佳方法。但是我需要结束此操作,因为即使子进程结束后,我也不想让我的应用程序永远等待。

有人知道解决方案吗?

注意:代码在这里,实际上是打字稿:https://github.com/goFrendiAsgard/chiml/blob/7065b57ba24d73c29dd54a28f9f7c9ebbf0fb269/src/libraries/cmd.ts

编辑(解决方法):我发现一种非常奇怪的解决方法是,将on errorprocess.stdin的侦听器都添加到subprocess.stdin中,因为我看到了一些{{1} } Unhandled error测试中的消息。这就是我添加监听器的方式:

jest

到目前为止,它可以正常运行(如果发生相同的错误,我会进行更新)。

0 个答案:

没有答案