本文介绍了Node.js:捕获`child_process.spawn` 的标准输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to capture in a custom stream outputs of a spawned child process.

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 作为它的执行.

It looks like child_process.spawn is not using stream.Writable.prototype.write nor stream.Writable.prototype._write for its execution.

例如

s.write = function() { console.log("this will never get printed"); };

还有,

s.__proto__._write = function() { console.log("this will never get printed"); };

看起来它使用文件描述符幕后child_process.spawn 写入文件.

It looks like it uses file descriptors under-the-hood to write from child_process.spawn to a file.

这样做不起作用:

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

那么,如何获取子进程的STDOUT内容?

So, how can I get the STDOUT contents of a child process?

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

What I want to achieve is to stream STDOUT of a child process to a socket. If I provide the socket directly to the child_process.spawn as a stdio parameter it closes the socket when it finishes, but I want to keep it open.

更新:

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

The solution is to use default {stdio: ['pipe', 'pipe', 'pipe']} options and listen to the created .stdout of the child process.

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

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

Now, to up the ante, a more challenging question:

--如何读取子进程的STDOUT并保留颜色?

-- How do you read the STDOUT of the child process and still preserve the colors?

例如,如果您像这样将 STDOUT 发送到 process.stdout:

For example, if you send STDOUT to process.stdout like so:

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

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

it will keep the colors and print colored output to the console, because the .isTTY property is set to true on process.stdout.

process.stdout.isTTY // true

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

Now if you use the default {stdio: ['pipe', 'pipe', 'pipe']}, the data you will read will be stripped of console colors. How do you get the colors?

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

One way to do that would be creating your own custom stream with fs.createWriteStream, because child_process.spawn requires your streams to have a file descriptor.

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

Then setting .isTTY of that stream to true, to preserve colors.

最后,您需要捕获 child_process.spawn 写入该流的数据,但由于 child_process.spawn 不使用 .prototype.write.prototype._write 流,您需要以其他hacky方式捕获其内容.

And finally you would need to capture the data what child_process.spawn writes to that stream, but since child_process.spawn does not use .prototype.write nor .prototype._write of the stream, you would need to capture its contents in some other hacky way.

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

That's probably why child_process.spawn requires your stream to have a file descriptor because it bypasses the .prototype.write call and writes directly to the file under-the-hood.

有什么想法可以实现吗?

Any ideas how to implement this?

推荐答案

你可以不用临时文件:

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

这篇关于Node.js:捕获`child_process.spawn` 的标准输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 16:42