节点 child_process 中的奇怪管道行为?

Weird pipe behavior in node's child_process?

我有一个 shell 命令在终端中运行良好,但当由节点的 child_process 执行时却出错。

这是在终端中使用的命令 file.json 是一个 json 文件):

cat /tmp/file.json | jq

这是 运行 来自 child_process 的相同命令:

var cp = require("child_process");

var command = "cat /tmp/gen_json | jq";
cp.exec(command, function(err, stdout, stderr) {
  stderr ? console.log(stderr) : console.log(stdout);
});

产生:

jq - commandline JSON processor [version 1.5-1-a5b5cbe]
Usage: jq [options] <jq filter> [file...]

    jq is a tool for processing JSON inputs, applying the
    given filter to its JSON text inputs and producing the
    ...

这是 运行 jq 时显示的默认消息。就好像我只是 运行 jq 而没有前面的管道。

如果过滤器被省略,则捕获在 jqattempts to intelligently infer the default filter 中。

也就是说,当输出到终端(TTY)时,过滤器可以省略,它默认为.(漂亮的印刷品)。这就是为什么在终端中你可以写:

cat file | jq           # or:  jq < file

而不是:

cat file | jq .         # or:  jq . file

当从 node 调用时,stdinstdout 重定向 jq 需要 filter 参数。这就是您必须明确指定它的原因:

var command = "cat /tmp/gen_json | jq .";

或者,甚至更好(避免猫科动物虐待):

var command = "jq . /tmp/gen_json";