这里已经有一些关于node.js执行命令和输出数据的问题,但我仍然无法解决这个问题。我想要的是使用node.js我想执行一个运行很长时间的python脚本并产生一些中间输出。我想在生成后立即将这些输出流式传输到客户端。我尝试了以下内容,但我得到的是,只有在命令完成后才能获得整个输出。如何让它实时将数据传递到套接字?感谢。
function run_cmd(cmd, args) {
var spawn = require('child_process').spawn,
child = spawn(cmd, args);
return child;
}
io.sockets.on('connection', function (socket) {
var foo = new run_cmd('python', ['test.py']);
foo.stdout.setEncoding('utf-8');
foo.stdout.on('data', function(data) {
console.log('sending data');
io.sockets.emit('terminal', {output: data});;
});
);
答案 0 :(得分:6)
你所有的node.js代码都没问题。你的代码只发送一次数据,因为你的代码只获取一次数据。
关键是put或print命令不足以触发foo.stdout.on 尝试在要在ruby代码中发送块的位置添加'$ stdout.flush'。 您需要明确订购输出数据。
这是我的测试代码。
JS
var spawn = require('child_process').spawn;
var cmd = spawn('ruby', ['testRuby.rb']);
var counter = 0;
cmd.stdout.on('data', function(data) {
counter ++;
console.log('stdout: ' + data);
});
cmd.stderr.on('data', function(data) {
console.log('stderr: ' + data);
});
cmd.on('exit', function(code) {
console.log('exit code: ' + code);
console.log(counter);
});
testRuby.rb
def execute_each_sec(sleep_sec)
yield
sleep sleep_sec
end
5.times do
execute_each_sec(1) do ||
puts "CurrentTime:#{Time.now}"
$stdout.flush
end
end
你可以看到我正在调用$ stdout.flush来在testRuby.rb中显式输出数据。 如果我删除它,node.js将不会得到任何东西,直到testRuby.rb的执行完成。
<强>编辑强> 大声笑我的坏。我使用ruby而不是python。 在python的情况下,使用sys.stdout.flush(),如svkk所说
修改强>
在python中,您还可以使用-u
标志强制它在每次打印后刷新。