Node.js child_process exec 的标准输出被缩短
Posted
技术标签:
【中文标题】Node.js child_process exec 的标准输出被缩短【英文标题】:Stdout of Node.js child_process exec is cut short 【发布时间】:2014-02-06 22:56:04 【问题描述】:在 Node.js 中,我使用 child_process 模块的 exec 命令调用 Java 中的算法,该算法将大量文本返回到标准输出,然后我对其进行解析和使用。大部分我都能捕捉到,但是当它超过一定的行数时,内容就会被截断。
exec("sh target/bin/solver "+fields.dimx+" "+fields.dimy, function(error, stdout, stderr)
//do stuff with stdout
我尝试过使用 setTimeouts 和回调,但没有成功,但我确实觉得这种情况正在发生,因为我在代码中引用了标准输出,然后才能完全检索它。我已经测试过 stdout 实际上是第一次发生数据丢失的地方。这不是进一步的异步问题。我也在我的本地机器和 Heroku 上对此进行了测试,并且发生了完全相同的问题,每次都在完全相同的行号处截断。
您有什么想法或建议可以对此有所帮助吗?
【问题讨论】:
另见:Stdout buffer issue using node child_process 【参考方案1】:我让 exec.stdout.on('end') 回调永远挂在 @damphat 解决方案中。
另一种解决方案是在 exec 的选项中增加缓冲区大小:参见文档here
encoding: 'utf8',
timeout: 0,
maxBuffer: 200*1024, //increase here
killSignal: 'SIGTERM',
cwd: null,
env: null
引用:maxBuffer 指定 stdout 或 stderr 上允许的最大数据量 - 如果超过此值,则子进程将被终止。我现在使用以下内容:这不需要处理标准输出中由逗号分隔的块的分隔部分,而不是接受的解决方案。
exec('dir /b /O-D ^2014*',
maxBuffer: 2000 * 1024 //quick fix
, function(error, stdout, stderr)
list_of_filenames = stdout.split('\r\n'); //adapt to your line ending char
console.log("Found %s files in the replay folder", list_of_filenames.length)
);
【讨论】:
【参考方案2】:这个问题的真正(也是最好的)解决方案是使用 spawn 而不是 exec。 如in this article 所述,spawn 更适合处理大量数据:
child_process.exec 返回子进程的整个缓冲区输出。默认情况下,缓冲区大小设置为 200k。如果子进程返回的内容不止于此,您的程序将崩溃并显示错误消息“错误:超出最大缓冲区”。您可以通过在 exec 选项中设置更大的缓冲区大小来解决该问题。但是您不应该这样做,因为 exec 不适用于将 HUGE 缓冲区返回给 Node 的进程。你应该使用 spawn 。那么你用 exec 做什么呢?使用它来运行返回结果状态而不是数据的程序。
spawn 需要与 exec 不同的语法:
var proc = spawn('sh', ['target/bin/solver', 'fields.dimx', 'fields.dimy']);
proc.on("exit", function(exitCode)
console.log('process exited with code ' + exitCode);
);
proc.stdout.on("data", function(chunk)
console.log('received chunk ' + chunk);
);
proc.stdout.on("end", function()
console.log("finished collecting data chunks from stdout");
);
【讨论】:
感谢您的回答!它帮助我了解我的exec
由于 1MB 的输出而返回错误。不幸的是,exec
的错误对象只返回了命令名称,而没有详细说明错误原因:"cmd":"./read_mail.sh"
【参考方案3】:
编辑:
我在我的电脑(windows
)上尝试了dir /s
并遇到了同样的问题(它看起来像一个错误),这段代码为我解决了这个问题:
var exec = require('child_process').exec;
function my_exec(command, callback)
var proc = exec(command);
var list = [];
proc.stdout.setEncoding('utf8');
proc.stdout.on('data', function (chunk)
list.push(chunk);
);
proc.stdout.on('end', function ()
callback(list.join());
);
my_exec('dir /s', function (stdout)
console.log(stdout);
)
【讨论】:
为什么你认为它看起来像一个错误?请看我的回答 @olamotte 你可以看到这个答案的历史,我增加了缓冲区大小,但它对我不起作用。以上是关于Node.js child_process exec 的标准输出被缩短的主要内容,如果未能解决你的问题,请参考以下文章
node.js 安全/转义中的 child_process 生成
如何在 Node.JS 中获取生成的 child_process 的输出?
如何模拟 Node.js child_process spawn 函数?
Node.js child_process exec 的标准输出被缩短