node.js порождает дочерний процесс в интерактивном режиме с отдельными потоками stdout и stderr

Рассмотрим следующую C-программу (test.c):

#include <stdio.h>

int main() {
  printf("string out 1\n");
  fprintf(stderr, "string err 1\n");
  getchar();
  printf("string out 2\n");
  fprintf(stderr, "string err 2\n");
  fclose(stdout);
}

Который должен напечатать строку в stdout, строку в stderr, затем ждать ввода пользователя, затем другую строку в stdout и другую строку в stderr. Очень простой! После компиляции и запуска в командной строке вывод программы после завершения (пользовательский ввод получен для getchar ()):

$ ./test 
string out 1
string err 1

string out 2
string err 2

При попытке порождать эту программу как дочерний процесс, используя nodejs со следующим кодом:

var TEST_EXEC = './test';

var spawn = require('child_process').spawn;
var test = spawn(TEST_EXEC);

test.stdout.on('data', function (data) {
  console.log('stdout: ' + data);
});

test.stderr.on('data', function (data) {
  console.log('stderr: ' + data);
});

// Simulate entering data for getchar() after 1 second
setTimeout(function() {
  test.stdin.write('\n');
}, 1000);

Вывод выглядит так:

$ nodejs test.js 
stderr: string err 1

stdout: string out 1
string out 2

stderr: string err 2

Очень отличается от вывода, как видно при запуске ./test в терминале. Это потому, что программа ./test не запускается в интерактивной оболочке при порождении nodejs. Поток stdout test.c буферизуется, и при запуске в терминале, как только достигается \ n, буфер сбрасывается, но при порождении таким образом с помощью узла буфер не очищается. Эту проблему можно решить либо путем очистки стандартного вывода после каждой печати, либо путем изменения потока стандартного вывода, чтобы он был буферизован, чтобы он сразу очищал все данные. Предполагая, что источник test.c недоступен или не может быть изменен, ни один из двух упомянутых параметров очистки не может быть реализован.

Затем я начал изучать эмуляцию интерактивной оболочки: есть pty.js (псевдо-терминал), который хорошо работает, например:

var spawn = require('pty.js').spawn;
var test = spawn(TEST_EXEC);

test.on('data', function (data) {
  console.log('data: ' + data);
});

// Simulate entering data for getchar() after 1 second
setTimeout(function() {
  test.write('\n');
}, 1000);

Какие выводы:

$ nodejs test.js
data: string out 1
string err 1

data: 

data: string out 2
string err 2

Однако и stdout, и stderr объединены вместе (как вы могли бы видеть при запуске программы в терминале), и я не могу придумать способ отделить данные от потоков.

Так что вопрос ..

Есть ли способ использовать nodejs для получения вывода, как видно при запуске ./test без изменения кода test.c? Либо с помощью эмуляции терминала или нереста процесса, либо любым другим способом?

Ура!

Ответы на вопрос(3)

Ваш ответ на вопрос