Node.js:捕获`child_process.spawn`的STDOUT

Vad*_*Vad 7 javascript stream node.js

我需要捕获生成的子进程的自定义输出.

child_process.spawn(command[, args][, options])
Run Code Online (Sandbox Code Playgroud)

例如,

var s = fs.createWriteStream('/tmp/test.txt');
child_process.spawn('ifconfig', [], {stdio: [null, s, null]})
Run Code Online (Sandbox Code Playgroud)

现在我如何/tmp/test.txt实时阅读?

它看起来像child_process.spawn没有使用stream.Writable.prototype.write,也没有stream.Writable.prototype._write为它的执行.

例如,

s.write = function() { console.log("this will never get printed"); };
Run Code Online (Sandbox Code Playgroud)

以及,

s.__proto__._write = function() { console.log("this will never get printed"); };
Run Code Online (Sandbox Code Playgroud)

看起来它使用引擎盖下的文件描述符来写入child_process.spawn文件.

这样做不起作用:

var s2 = fs.createReadStream('/tmp/test.txt');
s2.on("data", function() { console.log("this will never get printed either"); });
Run Code Online (Sandbox Code Playgroud)

那么,我怎样才能获得STDOUT子进程的内容?

我想要实现的是将STDOUT子进程流转换为套接字.如果我将套接字直接提供child_process.spawnstdio参数作为参数,它会在套接字完成后关闭套接字,但我想保持套接字打开.

更新:

解决方案是使用默认{stdio: ['pipe', 'pipe', 'pipe']}选项并侦听.stdout子进程的创建.

var cmd = child_process.spaw('ifconfig');
cmd.stdout.on("data", (data) => { ... });
Run Code Online (Sandbox Code Playgroud)

现在,提高赌注,一个更具挑战性的问题:

- 你如何阅读STDOUT儿童过程并仍然保留颜色?

例如,如果您发送STDOUTprocess.stdout像这样:

child_process.spawn('ifconfig', [], {stdio: [null, process.stdout, null]});
Run Code Online (Sandbox Code Playgroud)

它将保持颜色并将彩色输出打印到控制台,因为该.isTTY属性设置为trueon process.stdout.

process.stdout.isTTY // true
Run Code Online (Sandbox Code Playgroud)

现在,如果您使用默认值{stdio: ['pipe', 'pipe', 'pipe']},您将读取的数据将被剥离控制台颜色.你怎么得到颜色?

一种方法是使用,创建自己的自定义流fs.createWriteStream,因为child_process.spawn要求您的流具有文件描述符.

然后.isTTY将该流设置为true,以保留颜色.

最后,你将需要捕捉什么数据child_process.spawn写入到数据流,但由于child_process.spawn没有使用.prototype.write,也没有.prototype._write流,你就需要捕获其内容在其他一些哈克方式.

这可能是为什么child_process.spawn要求您的流具有文件描述符,因为它绕过.prototype.write调用并直​​接写入引擎下的文件.

任何想法如何实现这一点?

小智 6

您可以在不使用临时文件的情况下进行操作:

var process = child_process.spawn(command[, args][, options]);
process.stdout.on('data', function (chunk) {
    console.log(chunk);
});
Run Code Online (Sandbox Code Playgroud)