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

问题描述:

我有一个shell命令,在终端运行正常但由节点的child_process执行错误。节点的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 
    ... 

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

+0

不涉及到管道的行为,但你并不需要在这里'cat' (如果这是你正在运行的真正命令)。试试'jq'..filter ..'/ tmp/file.json'。 – randomir

+0

@randomir在我的情况下,我确实需要'cat',因为如果我运行'jq/tmp/file.json',它会打断'unexpected'/''。当'cat'在'jq'之前解析文件时,我没有看到这个错误。 (用pastebin更新问题到json) –

+1

看起来像'jq'需要强制过滤器,请尝试:'cat file | jq'。''。这也解决了你的其他问题:'jq'。' file'。 – randomir

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

即,当输出变为终端(TTY),所述过滤器可以省略,其默认值为.(漂亮打印)。这就是为什么在终端,你可以这样写:

cat file | jq   # or: jq < file 

代替:

cat file | jq .   # or: jq . file 

当从node调用,但是,随着stdinstdout重定向jq需要过滤说法。这就是为什么你必须明确地指定它:

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

,或者甚至更好(避免滥用猫):

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

'jq'。''可以简化为:'jq。' – peak

+1

这是真的,已更新。谢谢! – randomir