Node.js 有没有办法使子进程输出流更频繁地刷新其数据?
我正在尝试通过管道将子进程的标准输出传输到父进程的标准输出:Node.js 有没有办法使子进程输出流更频繁地刷新其数据?,node.js,Node.js,我正在尝试通过管道将子进程的标准输出传输到父进程的标准输出: import {exec} from 'child_process'; console.log(new Date() + " starting") const child = exec(/* some command */); child.stdout.pipe(process.stdout); 这是可行的,但相对于管道缓冲区的大小,子进程生成数据的速度非常慢。数据以大块形式出现,并不频繁 例如,如果我像这样观察子输出流: chi
import {exec} from 'child_process';
console.log(new Date() + " starting")
const child = exec(/* some command */);
child.stdout.pipe(process.stdout);
这是可行的,但相对于管道缓冲区的大小,子进程生成数据的速度非常慢。数据以大块形式出现,并不频繁
例如,如果我像这样观察子输出流:
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
有没有办法让子输出流使用更小的缓冲区或更频繁地刷新?操作系统和子进程控制输出缓冲 例如,Python有一个导致刷新写入的
-u
选项(还有PYTHONUNBUFFERED
env变量)。根据问题改编的以下示例显示了在使用无缓冲和正常输出时,每秒向屏幕写入一个整数的命令的行为差异
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()
如果正在运行的子进程没有用于刷新输出的等效选项或配置,则包括通过修改子进程的运行方式、分配伪终端或直接修改其缓冲区来禁用缓冲输出的许多技巧
还有一个和,它将生成带有伪终端的进程,这个伪终端类似于expects命令。我以前没有使用过这两个模块,所以不能保证它们 该命令必须刷新其缓冲区。通常无法从外部强制刷新。需要刷新的是父级,而不是子级。因此,在循环中手动读取流对我来说有意义吗?这会使我在需要数据时可以访问数据吗?@Matt底层子进程经常打印到其输出中(只是看起来与节点流缓冲区的大小相比不是很多)。子进程命令中也没有管道。嗨,Matt。谢谢你的回答和你的评论。我没有时间进一步探讨这个问题。我不能依赖于
expectes
/unbuffer
,但会查看npm包。