【发布时间】:2017-01-23 17:20:26
【问题描述】:
我有以下“机器人”python 脚本:
#! /usr/bin/env python3
import asyncio
import sys
def callback(*args):
data = sys.stdin.readline()[:-1]
print('ECHO: {}'.format(data), flush=True)
if data == 'EOF':
loop.stop()
print('Bot spawning!')
loop = asyncio.get_event_loop()
task = loop.add_reader(sys.stdin.fileno(), callback)
loop.run_forever()
loop.close()
print('Bot dead')
应该由这个节点应用程序处理:
#! /usr/bin/env node
const createInterface = require('readline').createInterface
const spawn = require('child_process').spawn
const lines = [
'I',
'LOVE',
'DEAD',
'BEEF',
'EOF',
]
const bot = spawn('./poc.py')
const rl = createInterface({
input: bot.stdout,
})
rl.on('line', line => {
console.log('BOT SAYS', new Array(line))
})
// bot.stdout.on('data', data => {
// console.log(`BOT SAYS: ${data}`)
// })
bot.stdin.on('error', (err) => console.log(err))
try {
console.log('Dispatching lines...')
lines.forEach( line => {
console.log('Connected', bot.connected)
console.log('Sending', line)
bot.stdin.write(`${line}\n`)
})
}
finally {
// bot.stdin.end()
}
问题是,除非我取消注释 bot.stdin.end() 行,否则我不会从机器人获得任何输出(在几次运行中,我得到了两行,但不是全部)。
我尝试了不同的方法,例如直接从 bot.stdout 读取,或者在 python 程序中显式刷新缓冲区,或者使用 execFile 而不是 spawn...但都无济于事。
所以我的问题是:如何让节点程序通过stdin 和stdout 与另一个进程进行交互通信,而不必关闭管道或等待所述进程的执行完成?
也许我应该采用完全不同的方法?
编辑:在我的 Fedora 25 工作站上运行上述代码会导致以下输出和程序不确定地挂起:
[] % ./poc.js
Dispatching lines...
Connected false
Sending I
Connected false
Sending LOVE
Connected false
Sending DEAD
Connected false
Sending BEEF
Connected false
Sending EOF
BOT SAYS [ 'Bot spawning!' ]
BOT SAYS [ 'ECHO: I' ]
请注意,子进程bot 一直处于断开状态,但仍然处理了两行输入...
【问题讨论】:
标签: python node.js pipe python-3.5