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

我需要捕获一个自定义的stream产生的subprocess的输出。

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.writestream.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"); }); 

那么,如何获得subprocess的STDOUT内容呢?

我想要实现的是将一个subprocess的STDOUTstream传输到一个套接字。 如果我将套接字作为stdio参数直接提供给child_process.spawn ,它将在完成时closures套接字,但是我想保持它打开状态。

更新:

解决方法是使用默认的{stdio: ['pipe', 'pipe', 'pipe']}选项并监听创build的.stdoutsubprocess。

 var cmd = child_process.spaw('ifconfig'); cmd.stdout.on("data", (data) => { ... }); 

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

– 如何读取subprocess的STDOUT并保持颜色?

例如,如果您将STDOUT发送到process.stdout如下所示:

 child_process.spawn('ifconfig', [], {stdio: [null, process.stdout, null]}); 

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

 process.stdout.isTTY // true 

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

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

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

最后,您需要捕获child_process.spawn写入该数据stream的数据,但是由于child_process.spawn不使用.prototype.write.prototype._write这个stream,所以您需要在其他一些hacky中捕获它的内容办法。

这可能是为什么child_process.spawn需要你的stream有一个文件描述符,因为它绕过.prototype.write调用,并直接写入文件引擎

任何想法如何实现这个?

你可以做到这一点,而不使用临时文件:

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

嗨,我正在打电话,但我会尽力引导你。 如果需要,我会在计算机附近进行说明

我想你想要的是从一个产卵读取stdout ,并与数据做一些事情?

你可以给spawn一个variables名称,而不是只运行该函数,例如:

 var child = spawn(); 

然后听听输出:

 child.stdout.on('data', function(data) { console.log(data.toString()); }); 

你可以用它来把数据写到一个文件或者任何你想要用它来做的事情上。

stdio选项需要文件描述符,而不是stream对象,所以一种方法是使用fs.openSync()来创build输出文件描述符。

以你的第一个例子,但使用fs.openSync()

 var s = fs.openSync('/tmp/test.txt', 'w'); var p = child_process.spawn('ifconfig', [], {stdio: [process.stdin, s, process.stderr]}); 

你也可以将stdout和stderr都设置为相同的文件描述符(与bash的2>&1 )。

完成后需要closures文件,所以:

 p.on('close', function(code) { fs.closeSync(s); // do something useful with the exit code ... });