Node.js子进程生成缓冲问题



对于我的一个项目,我本质上希望能够将命令传递给 Node.js 脚本并让它执行它并逐行记录输出。这就是我现在拥有的:

var child_process = require('child_process');
var child_spawn = child_process.spawn('ruby', ['test.rb']);
child_spawn.stdout.on('data', function(data) {
    console.log('stdout: ' + data);
});

现在,当我尾部 -f 系统日志时,它就像我一样工作,除了但是当我用我编写的微不足道的 ruby 脚本测试它时,它会立即接收所有输出,就好像它是缓冲的一样?

有问题的脚本是:

puts "hello"
sleep(1)
puts "there"
sleep(1)
puts "my"
sleep(1)
puts "name"
sleep(1)
puts "is"
sleep(1)
puts "james"

当我自己运行它时,它的工作原理就像我相信你可以想象的那样,一次打印出一行,中间有第二个间隙。

在节点文档(http://nodejs.org/api/child_process.html)上,我看到了这个:

(请注意,某些程序在内部使用行缓冲 I/O。这不会影响节点.js但这意味着您发送到子进程的数据不会立即被消耗。

这就是这里正在发生的事情吗,有没有办法解决它?

这正是发生的事情。检查这个:

puts "hello"
STDOUT.flush
sleep(1)
puts "there"
STDOUT.flush
sleep(1)
puts "my"
STDOUT.flush
sleep(1)
puts "name"
STDOUT.flush
sleep(1)
puts "is"
STDOUT.flush
sleep(1)
puts "james"
STDOUT.flush

我假设 ruby 会检测 stout 是否不是 tty,如果是,则会缓冲所有输出并在脚本退出时刷新。放STDOUT.sync = true似乎可以解决这个问题。

vkurchatkin(https://stackoverflow.com/a/20978696/483271)的回答正确地解释了为什么会发生这种情况的原因。

然而,我实际上是如何解决这个问题的,通过使用这个 https://github.com/chjj/pty.js/(在 npm 上可用),它允许模拟终端,所以 Ruby 不会缓冲它的输出,并且似乎有一个兼容的 API 来child_process我目前所看到的。

最新更新