从标准input读取时,Node.js无法读取pythonsubprocess标准输出

我有一个node.js脚本启动一个pythonsubprocess并读取它的stdout。 只要Python进程不尝试从标准input读取,它就会工作。 然后父进程没有从孩子得到任何东西。

我在这里有node.js脚本和两个pythontesting用例:(这两个示例工作,如果你评论尝试从标准input读取的行)

第一个孩子:

import sys print('before') for line in sys.stdin: print(line) print('after') 

第二个孩子:

 import sys print('before') while True: line = sys.stdin.readline() if line != '': print(line) else: break print('after') 

家长:

 const spawn = require('child_process').spawn; let client = spawn('python', ['test1.py'], {cwd: '/tmp'}); client.stdout.on('data', (data) => { console.log(data.toString()); }); client.stderr.on('data', (data) => { console.log(data.toString()); }); client.on('close', () => { console.log('close'); }); client.on('exit', () => { console.log('exit'); }); client.on('disconnect', () => { console.log('disconnect'); }) 

一个进程的stdout可以是无缓冲的,行缓冲或块缓冲取决于进程是如何开始的。 特别是,从控制台启动的程序是行缓冲的,程序的stdout被redirect(到pipe道或文件)被块缓冲。 这样做是为了有效地增加总体的程序。 人们希望马上看到事情,所以terminal是行缓冲的,但其他程序和文件可以等待,并在更大的块中取得东西,所以它们是块缓冲。

您可以通过强制数据在每次写入时被stream通来修复python方面的问题。 你可以用print语句或sys.stdout对象本身来做到这一点

 print('line 1', flush=True) print('line 2') print('line 3') sys.stdout.flush() 

您也可以通过模拟一个terminal来修复它在node.js端,基本上欺骗程序,使其认为它正在显示给用户。

 const spawn = require('pty.js').spawn; 

这是更通用的 – 你不需要孩子的合作,使其工作。 但它可能会变得复杂。 有些subprocess获取有关附加tty的信息,以执行更复杂的操作,如创build菜单或颜色输出。 但它经常是一个很好的select。