我的目标是将某些流程执行的会话保存到json(类似[{ type: 'stdout', data: 'What's your name?' }, { type: 'stdin', data: 'Alex.' }, { type: 'stdout', data: 'Hi, Alex!' }]
)。我决定用nodejs来做,但是遇到了一些问题。生成的标准输出在通过管道传输和继承时的工作方式有所不同。因此,例如,我将此C代码(简单猜测数字游戏)编译为main
:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int random_num = 0;
int guessed_num = 0;
int counter = 0;
srand(time(NULL));
random_num = rand() % 10 + 1;
printf("Guess my number! ");
while(1) {
counter++;
scanf("%d", &guessed_num);
if (guessed_num == random_num) {
printf("You guessed correctly in %d tries! Congratulations!\n", counter);
break;
}
if (guessed_num < random_num)
printf("Your guess is too low. Guess again. ");
if (guessed_num > random_num)
printf("Your guess is too high. Guess again. ");
}
return 0;
}
这段JavaScript代码:
var spawn = require('child_process').spawn;
var child = spawn('./main', { stdio: 'inherited' });
该JavaScript代码的执行结果将是:
Guess my number! 1
Your guess is too low. Guess again. 2
Your guess is too low. Guess again. 3
You guessed correctly in 3 tries! Congratulations!
但是,当stdio
is时inherited
,我无法附加到任何流程流并将数据保存到json。所以我尝试了这个:
var spawn = require('child_process').spawn;
var child = spawn('./main', { stdio: 'pipe' });
child.stdout.on('data', function(data) { process.stdout.write(data) });
process.stdin.on('data', function(data) { child.stdin.write(data) });
并通过执行得到此结果:
1
2
3
Guess my number! Your guess is too low. Guess again. Your guess is too low. Guess again. You guessed correctly in 3 tries! Congratulations!
当子进程正在等待输入时,子进程的标准输出会以某种方式挂起。它可能与事件循环有关,但我不确定。无论如何,inherited
and的行为pipe
都非常不同,这似乎是错误的...
我该怎么办?也许有一些解决方法?
在inherited
模式下,C程序继承绑定到终端的描述符。终端是一个交互式设备,它会自动将要进行printf()
功能缓冲的功能设置stdout
为行缓冲(即遇到新行时刷新缓冲区)。
OTOH,在pipe
模式下,libc不会检测到交互式设备,而是切换到完全缓冲(即,仅在缓冲区已满或被fflush()
调用时才刷新缓冲区)。
一种解决方法是fflush(stdout)
在每次调用后printf()
调用,或者禁用所有缓冲stdout
:setvbuf(stdout, NULL, _IONBF, 0);
。
有关管道与终端缓冲的完整说明,请参见此答案,包括libc确定对的缓冲的示例stdout
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句