Ответ 1
Прежде всего, одна из вещей, препятствующих взаимодействию node с другими интерактивными оболочками, заключается в том, что дочернее приложение должно сохранять свое "интерактивное" поведение, даже если stdin
не похоже на терминал. python
здесь знал, что его stdin
не был терминалом, поэтому он отказался работать. Это можно переопределить, добавив флаг -i
в команду python.
Во-вторых, как вы уже упоминали в обновлении, вы забыли написать новый строковый символ для потока, поэтому программа вела себя так, как будто пользователь не нажал Enter. Да, это правильный путь, но отсутствие интерактивного режима не позволило вам получить какие-либо результаты.
Здесь вы можете сделать, чтобы отправить несколько входов в интерактивную оболочку, сохраняя при этом каждый результат по одному. Этот код будет устойчив к длительным выходам, накапливая их, пока не будет получена полная линия до выполнения другой команды. Одновременно может выполняться несколько инструкций, что может быть предпочтительным, если они не зависят от состояния родительского процесса. Не стесняйтесь экспериментировать с другими асинхронными структурами для достижения своей цели.
var cp = require('child_process');
var childProcess = cp.spawn('python', ['-i']);
childProcess.stdout.setEncoding('utf8')
var k = 0;
var data_line = '';
childProcess.stdout.on("data", function(data) {
data_line += data;
if (data_line[data_line.length-1] == '\n') {
// we've got new data (assuming each individual output ends with '\n')
var res = parseFloat(data_line);
data_line = ''; // reset the line of data
console.log('Result #', k, ': ', res);
k++;
// do something else now
if (k < 5) {
// double the previous result
childProcess.stdin.write('2 * + ' + res + '\n');
} else {
// that enough
childProcess.stdin.end();
}
}
});
childProcess.stdin.write('1 + 0\n');