首页 文章

从stdin读取时,Node.js无法读取python subprocess标准输出

提问于
浏览
1

我有一个node.js脚本,它启动一个python子进程并读取它的stdout . 只要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');
})

1 回答

  • 2

    进程 stdout 可以是无缓冲的,行缓冲的或块缓冲的,具体取决于进程的启动方式 . 特别是,从控制台启动的程序是行缓冲的,并且stdout被重定向(到管道或文件)的程序是块缓冲的 . 这样做是为了有效地提高整体计划 . 人们希望立即看到东西,所以终端是行缓冲的,但是其他程序和文件可以等待并获得更大的块,因此它们是块缓冲的 .

    您可以通过强制在每次写入时使数据流动来解决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的信息,以执行更复杂的操作,如创建菜单或颜色输出 . 但它经常是一个很好的选择 .

相关问题