有没有办法让子stream程输出stream更频繁地刷新其数据?

我正在尝试将一个subprocess的标准输出传递给父进程的标准输出:

import {exec} from 'child_process'; console.log(new Date() + " starting") const child = exec(/* some command */); child.stdout.pipe(process.stdout); 

这是有效的,但subprocess相对于pipe道缓冲区的大小,生成的数据相当缓慢。 数据大部分来自不常用的数据。

例如,如果我看这样的子输出stream:

 child.stdout.on('data', data => console.log(new Date(), data.length)); 

输出是

 2017-11-15T21:53:44.128Z starting 2017-11-15T21:53:58.319Z 8192 2017-11-15T21:54:02.321Z 8192 2017-11-15T21:54:07.384Z 8192 2017-11-15T21:54:11.333Z 8192 2017-11-15T21:54:15.281Z 8192 2017-11-15T21:54:19.008Z 3967 

有没有办法让子输出stream使用更小的缓冲区或更频繁的刷新?

操作系统和subprocess在输出缓冲控制。

作为一个例子,Python有一个-u选项,导致写入刷新(也是PYTHONUNBUFFERED env var)。 以下根据问题调整的示例显示了使用非缓冲和正常输出时每秒写入一个整数的命令的行为差异。

 const {exec} = require('child_process') function run(cmd){ return new Promise((resolve, reject) => { console.log("%s starting %s", Date.now(), cmd) const child = exec(cmd) child.stdout.pipe(process.stdout) child.stderr.pipe(process.stderr) child.on('exit', exit => { console.log('%s exit', Date.now(), exit) if ( exit === 0 ) return resolve(exit) reject(new Error(exit)) }) }) } async function go(){ await run('python -uc "import time; [print(i,str(time.sleep(1))) for i in range(10)]"') await run('python -c "import time; [print(i,str(time.sleep(1))) for i in range(10)]"') } go() 

如果正在运行的subprocess没有相应的选项或configuration来刷新输出,那么这个Unix + Linux的问题就包含了一些技巧,通过修改subprocess的运行方式来禁用缓冲输出,通过分配一个伪terminal或者修改它直接是缓冲区。

另外还有node-ptynode-pty2 ,它会用一个伪terminal产生进程,类似于unbuffer命令所要做的。 我以前没有使用任何模块,所以不能担保。