Javascript Node.js:捕获'child_process.spawn'的标准输出`

Javascript Node.js:捕获'child_process.spawn'的标准输出`,javascript,node.js,stream,Javascript,Node.js,Stream,我需要在自定义流中捕获衍生子进程的输出 child_process.spawn(command[, args][, options]) var cmd = child_process.spaw('ifconfig'); cmd.stdout.on("data", (data) => { ... }); 比如说, var s = fs.createWriteStream('/tmp/test.txt'); child_process.spawn('ifconfig', [], {stdi

我需要在自定义流中捕获衍生子进程的输出

child_process.spawn(command[, args][, options])
var cmd = child_process.spaw('ifconfig');
cmd.stdout.on("data", (data) => { ... });
比如说,

var s = fs.createWriteStream('/tmp/test.txt');
child_process.spawn('ifconfig', [], {stdio: [null, s, null]})
s.write = function() { console.log("this will never get printed"); };
现在如何实时读取
/tmp/test.txt

看起来
child\u进程.spawn
未使用
stream.Writable.prototype.write
stream.Writable.prototype.\u write
执行

比如说,

var s = fs.createWriteStream('/tmp/test.txt');
child_process.spawn('ifconfig', [], {stdio: [null, s, null]})
s.write = function() { console.log("this will never get printed"); };
以及

s.__proto__._write = function() { console.log("this will never get printed"); };
它看起来像是在后台使用文件描述符从
child\u进程.spawn
写入文件

这样做行不通:

var s2 = fs.createReadStream('/tmp/test.txt');
s2.on("data", function() { console.log("this will never get printed either"); });
那么,如何获取子进程的
STDOUT
内容呢

我想要实现的是将子进程的
STDOUT
流式传输到套接字。如果我将套接字直接提供给
child\u进程.spawn
作为
stdio
参数,那么它会在完成时关闭套接字,但我希望保持它打开

更新:

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

child_process.spawn(command[, args][, options])
var cmd = child_process.spaw('ifconfig');
cmd.stdout.on("data", (data) => { ... });
现在,为了提高赌注,一个更具挑战性的问题:

--如何读取子进程的
STDOUT
,并且仍然保留颜色

例如,如果将
STDOUT
发送到
process.STDOUT
如下:

child_process.spawn('ifconfig', [], {stdio: [null, process.stdout, null]});
它将保留颜色并将彩色输出打印到控制台,因为
进程.stdout上的
.isTTY
属性设置为
true

process.stdout.isTTY // true
现在,如果您使用默认的
{stdio:['pipe','pipe','pipe']}
,您将读取的数据将去除控制台颜色。你是怎么得到这些颜色的

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

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

最后,您需要捕获
child\u process.spawn
写入该流的数据,但由于
child\u process.spawn
不使用
.prototype.write
.prototype.\u write
流的内容,因此您需要以其他黑客方式捕获其内容

这可能就是
child\u process.spawn
要求流具有文件描述符的原因,因为它绕过了
.prototype.write
调用并直接写入引擎盖下的文件


如何实现这一点有什么想法吗?

无需使用临时文件即可:

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

嗨,我在打电话,但我会尽力给你指点方向。如果需要的话,我会在靠近电脑时澄清

我认为您想要的是从spawn中读取
stdout
,并对数据进行处理

您可以为spawn指定一个变量名,而不只是运行函数,例如:

var child = spawn();
然后听输出,如:

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

您可以使用它将数据写入一个文件或您想对其执行的任何操作

stdio
选项需要文件描述符,而不是流对象,因此一种方法是使用
fs.openSync()
创建输出文件描述符,然后使用它

以第一个示例为例,但使用
fs.openSync()

您还可以将stdout和stderr都设置为相同的文件描述符(与bash的
2>&1
具有相同的效果)

完成后,您需要关闭该文件,因此:

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

谢谢你的快速回复!这实际上是阻塞了语句之间的输出流,还是该间隔内的任何输出都丢失了?@AsadSaeeduddin不,它不会阻塞。