Node.js可以';当从stdin读取python子进程stdout时,不能读取它

Node.js可以';当从stdin读取python子进程stdout时,不能读取它,python,node.js,process,stdout,stdin,Python,Node.js,Process,Stdout,Stdin,我有一个node.js脚本,它启动python子进程并读取其标准输出。只要python进程不尝试从stdin读取数据,这种方法就可以工作。那么父进程就不会从子进程得到任何东西 我这里有node.js脚本和两个python测试用例:(如果您对试图从stdin读取的行进行注释,这两个示例都可以使用) 第一个孩子: import sys print('before') for line in sys.stdin: print(line) print('after') 第二个孩子: im

我有一个node.js脚本,它启动python子进程并读取其标准输出。只要python进程不尝试从stdin读取数据,这种方法就可以工作。那么父进程就不会从子进程得到任何东西

我这里有node.js脚本和两个python测试用例:(如果您对试图从stdin读取的行进行注释,这两个示例都可以使用)

第一个孩子:

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被重定向(到管道或文件)的程序是块缓冲的。这样做是为了有效地提高总体计划。人们希望立即看到东西,所以终端是行缓冲的,但其他程序和文件可以等待,并在更大的块中获取东西,所以它们是块缓冲的

通过在每次写入时强制对数据进行fluxhed,可以在python端解决这个问题。您可以使用
print
语句或
sys.stdout
对象本身执行此操作

print('line 1', flush=True)
print('line 2')
print('line 3')
sys.stdout.flush()
您还可以在node.js端通过模拟终端来修复它,基本上是诱使程序认为它正在向用户显示

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

这是更一般的-你不需要孩子的合作,使它的工作。但它可能会变得复杂。一些子进程获取有关附加tty的信息,以执行更复杂的操作,如创建菜单或颜色输出。但这通常是一个很好的选择。

我不知道node.js,但从python的角度来看,写了一行,但因为它是管道,而不是tty,所以它会被缓冲以等待更多数据。您可以执行
print('before',flush=True)
立即发送。然后它等待数据并。。。好您需要发送数据。
flush=True
技巧确实解决了问题。如果您将此作为答案发布,我将接受:)最好在
node.js
端使用类似
const spawn=require('pty.js').spawn的内容来修复此问题此问题讨论分割标准输出/错误流。我很乐意提供一个答案。。。但我不确定这是不是最好的答案……输入错误。那是“pty.js”,谢谢你的回答。pty解决方案可行,但我想再看看第一个想法。当我刷新stdout时,我可以从python接收输出,但我有另一个问题:当我使用
client.stdin.write('test')
将文本发送到子进程时,python程序中不会出现这种情况。我是否也必须以某种方式刷新stdin?我想是的。我真的不知道node.js,但是如果spawn设置了一个到子stdin的管道,那么它的块将被缓冲,并且有相同的问题。由于您正在阅读行,因此还需要包含换行符。