我有一个 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
可以是无缓冲的、行缓冲的或块缓冲的,具体取决于进程的启动方式。特别是,从控制台启动的程序是行缓冲的,而标准输出重定向(到管道或文件)的程序是块缓冲的。这样做是为了有效地提高整体计划。人们希望立即看到内容,因此终端是行缓冲的,但其他程序和文件可以等待并在更大的块中获取内容,因此它们是块缓冲的。
您可以通过强制在每次写入时刷新数据来解决 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 的信息来执行更复杂的操作,例如创建菜单或颜色输出。但这通常是一个不错的选择。
感谢
line buffer
的提示。
对于我的情况,解决方案是在js中写入py stdin时添加 + '\n'
this.python.stdin.write(JSON.stringify({ word_toLemmatize }) + '\n');
try:
for line in sys.stdin:
# Process the data
result = process_data(line.strip())
# Send the result back to Node.js
print(json.dumps(result))
# print(json.dumps(result), flush=True)
# print("\n", flush=True)
sys.stdout.flush()
except EOFError:
# End of input, exit the script
sys.exit()
node.js - Nodejs 子进程不会将数据从 python 脚本返回到标准输出 - 代码日志Nodejs 子进程不会将数据从 python 脚本返回到 stdout
node.js - ChildProcess:Python readline 无法读取 stdin - 代码日志
ChildProcess:Python readline 无法读取 stdin
Node.js 从标准输入读取时无法读取 python 子进程标准输出 - 代码日志 Node.js 从 stdin 读取时无法读取 python 子进程 stdout