2016-11-24 6 views
1

나는 python 서브 프로세스를 시작하고 stdout을 읽는 node.js 스크립트를 가지고 있습니다. 이것은 파이썬 프로세스가 stdin에서 읽으 려하지 않는 한 작동합니다. 그렇다면 부모 프로세스는 자식으로부터 아무 것도 얻지 못합니다.Node.js는 stdin에서 읽을 때 파이썬 subprocess stdout을 읽을 수 없습니다

첫째 아이 (당신은 표준 입력에서 읽으려고 줄 언급하는 경우 두 예제가 작동) :

import sys 

print('before') 

for line in sys.stdin: 
    print(line) 

print('after') 

둘째 아이를

본인은 Node.js를 스크립트와 여기에 두 파이썬 테스트 케이스를 :

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'); 
}) 
+0

node.js를 모르지만 파이썬 관점에서 볼 때 한 줄짜리지만, 파이프가 아닌 tty이기 때문에 더 많은 데이터를 기다리는 동안 버퍼링됩니다. 'print (before ', flush = True)'를 사용하면 즉시 보낼 수 있습니다. 그런 다음 데이터를 기다리고 ... 음 ... 데이터를 보내야합니다. – tdelaney

+0

'flush = True' 트릭이 문제를 해결했습니다. 이 질문을 답으로 게시하면 받아 들일 것입니다 :) – Martin

+0

'node.js' 측에서'const spawn = require ('pty.js'). spawn;과 같이 수정하는 것이 더 나을 것 같습니다. stdout/err 스트림 분할에 대해 설명합니다. http://stackoverflow.com/questions/15339379/node-js-spawning-a-child-process-interactively-with-separate-stdout-and-stderr-s. 나는 대답을 해줘서 기쁩니다 ...하지만 나는 그 최선의 대답을 확신하지 못합니다. – tdelaney

답변

2

프로세스 stdout은 프로세스 시작 방법에 따라 버퍼링되지 않거나, 라인 버퍼링되거나, 블록 버퍼링 될 수 있습니다. 특히, 콘솔에서 시작된 프로그램은 라인 버퍼 처리되고 stdout이 파이프 또는 파일로 리디렉션되는 프로그램은 블록 버퍼링됩니다. 이는 전체 프로그램을 효율적으로 향상시키기 위해 수행됩니다. 사람들은 즉시 터미널을 라인 버퍼링 할 수 있지만 다른 프로그램과 파일은 기다릴 수 있고 더 큰 블록에서 물건을 얻을 수 있도록 상황을보고 싶어하므로 버퍼링이 차단됩니다.

파이썬 측에서는 각 쓰기에 데이터를 강제로 적용하여 문제를 해결할 수 있습니다. 당신은 print 문 또는 자체가

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

또한 기본적으로는 사용자에게 표시되는 생각으로 프로그램을 속여, 터미널을 에뮬레이션하여 Node.js를 측면에 문제를 해결할 수있는 sys.stdout 객체와이 작업을 수행 할 수 있습니다.

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

이것은 더 일반적입니다. 어린이의 협조가 필요하지 않습니다. 하지만 복잡해질 수 있습니다. 어떤 자식 프로세스는 첨부 된 tty에 대한 정보를 얻어서 메뉴 또는 색상 출력 생성과 같은 더 복잡한 작업을 수행합니다. 그러나 자주 그것의 훌륭한 선택.

+0

답해 주셔서 감사합니다. pty 솔루션이 작동하지만 첫 번째 아이디어를 다시 한 번 살펴보고 싶습니다. stdout을 플러시 할 때 파이썬에서 출력물을받을 수 있지만 또 다른 문제점이 있습니다 :'client.stdin.write ('test')를 사용하여 자식 프로세스에 텍스트를 보낼 때 이것은 파이썬 프로그램에 나타나지 않습니다. 'stdin'도 역시 플러시해야합니까? – Martin

+0

나는 그렇게 생각한다. 나는 node.js를 정말로 모른다. 그러나 spawn이 자식 stdin에 파이프를 설정하면 그 블록은 버퍼링되고 같은 문제를 갖는다. 당신이 줄들을 읽고 있기 때문에, 당신은 또한 줄 바꿈을 포함 할 필요가 있습니다. – tdelaney

+0

개행이 트릭을했습니다. 나 자신을 생각해야 했어. – Martin