我需要捕获生成的子进程的自定义流输出。
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
来执行。
例如,
s.write = function() { console.log("this will never get printed"); };
以及
s.__proto__._write = function() { console.log("this will never get printed"); };
看起来它使用文件描述符 under-the-hood 从child_process.spawn
写入文件。
这样做不起作用:
var s2 = fs.createReadStream('/tmp/test.txt');
s2.on("data", function() { console.log("this will never get printed either"); });
那么,我怎样才能获得子进程的STDOUT
内容?
我想要实现的是将子进程的STDOUT
流式传输到套接字。如果我将套接字作为child_process.spawn
参数直接提供给stdio
,它会在套接字完成时关闭套接字,但我想保持套接字打开。
更新
解决方案是使用默认的{stdio: ['pipe', 'pipe', 'pipe']}
选项,并聆听子进程的创建.stdout
。
var cmd = child_process.spaw('ifconfig');
cmd.stdout.on("data", (data) => { ... });
现在,提高赌注是一个更具挑战性的问题:
- 您如何阅读子进程的STDOUT
并仍然保留颜色?
例如,如果您将STDOUT
发送给process.stdout
,请执行以下操作:
child_process.spawn('ifconfig', [], {stdio: [null, process.stdout, null]});
它会保留颜色并将彩色输出打印到控制台,因为.isTTY
属性设置为true
上的process.stdout
。
process.stdout.isTTY // true
现在,如果您使用默认的{stdio: ['pipe', 'pipe', 'pipe']}
,您将阅读的数据将被剥离控制台颜色。你怎么得到颜色?
执行此操作的一种方法是使用fs.createWriteStream
创建自己的自定义流,因为child_process.spawn
要求您的流具有文件描述符。
然后将该流的.isTTY
设置为true
,以保留颜色。
最后,您需要捕获child_process.spawn
写入该流的数据,但由于child_process.spawn
不使用流的.prototype.write
或.prototype._write
,您将需要需要以其他一些 hacky 方式捕获其内容。
这可能是child_process.spawn
要求您的流拥有文件描述符的原因,因为它绕过.prototype.write
调用并直接写入文件 under-the-hood 。
有任何想法如何实现这个?
答案 0 :(得分:5)
您可以在不使用临时文件的情况下执行此操作:
var process = child_process.spawn(command[, args][, options]);
process.stdout.on('data', function (chunk) {
console.log(chunk);
});
答案 1 :(得分:2)
嗨,我在手机上,但我会尽力指导你。如果需要,我会在计算机附近澄清
我认为你想要的是从产卵中读取stdout
并对数据做些什么?
您可以为spawn提供变量名称,而不是仅运行该函数,例如:
var child = spawn();
然后听取输出:
child.stdout.on('data', function(data) {
console.log(data.toString());
});
您可以使用它将数据写入文件或您可能想要使用的任何内容。
答案 2 :(得分:2)
stdio
选项需要文件描述符,而不是流对象,所以一种方法是使用use fs.openSync()
来创建输出文件描述符和我们。
采用第一个例子,但使用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' s 2>&1
相同)。
完成后您需要关闭文件,所以:
p.on('close', function(code) {
fs.closeSync(s);
// do something useful with the exit code ...
});