Мне нужно записать в пользовательский поток выход из порожденного дочернего процесса.Node.js: Захват STDOUT из `child_process.spawn`
child_process.spawn(command[, args][, options])
Например,
var s = fs.createWriteStream('/tmp/test.txt');
child_process.spawn('ifconfig', [], {stdio: [null, s, null]})
Теперь, как я прочитал из /tmp/test.txt
в режиме реального времени?
Похоже, что child_process.spawn
не использует stream.Writable.prototype.write
или stream.Writable.prototype._write
для его исполнения.
Например,
s.write = function() { console.log("this will never get printed"); };
Как,
s.__proto__._write = function() { console.log("this will never get printed"); };
Похоже, он использует файловые дескрипторы под капотом писать с child_process.spawn
в файл.
Делать это не работает:
var s2 = fs.createReadStream('/tmp/test.txt');
s2.on("data", function() { console.log("this will never get printed either"); });
Итак, как я могу получить STDOUT
содержимое дочернего процесса?
То, что я хочу достичь, - это поток STDOUT
дочернего процесса в сокет. Если я предоставляю сокет непосредственно в child_process.spawn
как параметр stdio
, он закрывает сокет, когда он заканчивается, но я хочу, чтобы он был открыт.
Update:
Решение использовать по умолчанию {stdio: ['pipe', 'pipe', 'pipe']}
параметры и прослушивания созданного .stdout
дочернего процесса.
var cmd = child_process.spaw('ifconfig');
cmd.stdout.on("data", (data) => { ... });
Теперь, чтобы поднять ставки, более сложный вопрос:
- Как вы читаете STDOUT
дочернего процесса и до сих пор сохраняют цвета?
Например, если вы отправляете STDOUT
в process.stdout
так:
child_process.spawn('ifconfig', [], {stdio: [null, process.stdout, null]});
он будет держать цвета и печать цветной вывод на консоль, потому что свойство .isTTY
устанавливается в true
на process.stdout
.
process.stdout.isTTY // true
Теперь, если вы используете по умолчанию {stdio: ['pipe', 'pipe', 'pipe']}
, данные, которые вы будете читать будет лишен консольных цветов. Как вы получаете цвета?
Один из способов сделать это: создать свой собственный поток с помощью fs.createWriteStream
, потому что child_process.spawn
требует, чтобы ваши потоки имели файловый дескриптор.
Затем установка .isTTY
этого потока на true
, чтобы сохранить цвета.
И, наконец, вам нужно будет захватить данные, что child_process.spawn
записывает в этот поток, но так как child_process.spawn
не использует .prototype.write
ни .prototype._write
потока, вам нужно будет захватить его содержимое в каком-либо другом Hacky способа.
Вот почему, вероятно child_process.spawn
требует вашего потока иметь дескриптор файла, потому что он обходит .prototype.write
вызов и записывает непосредственно в файл под капотом.
Любые идеи, как реализовать это?
работает как шарм! – Vad
Действительно ли это блокирует выходной поток между операторами или какой-либо вывод в этом интервале потерян? –
@AsadSaeeduddin нет, он не блокируется. – Magomogo