问题描述
我需要在生成的子进程的自定义流输出中捕获.
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` 的标准输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!