2009-11-04 2 views
4

communicate의 설명서는 말한다 : 공정한 번만 하위 프로세스와 통신 할 수 있습니까?

상호 작용 : 표준 입력에 데이터를 전송합니다. 파일 끝에 도달 할 때까지 stdout 및 stderr에서 데이터를 읽습니다. 프로세스가 종료 될 때까지 기다립니다.

프로세스에 입력을 두 번 이상 보내야 할 경우 어떻게합니까? 예를 들어 프로세스를 생성하고 데이터를 보내면 프로세스가 그 결과를 반환하고 출력을 반환 한 다음 입력을 다시 보내야합니다. 어떻게 처리할까요?

답변

2

이렇게하려면 subprocess을 사용하지 마십시오. 버퍼링과 관련하여 통증이 생깁니다.

이 목적으로 pexpect을 권장합니다. 아주 잘 작동합니다. 불행히도 지금은 창문 아래에서 작동하지 않습니다. 포트에 대해 들었는데 (더 이상 찾을 수 없습니다).

+0

나는 고통을 기억합니다. – Casebash

3

그런 다음 .communicate()을 사용할 수 없습니다. 스트림을 폴링하거나 select 또는 FD 변경 (예 : gtk 및 Qt 모두 해당 도구를 사용할 수 있음)을들을 수있는 다른 방법을 사용할 수 있습니다.

1

여기 제가 작성한 모듈입니다. 버퍼링 문제를 피하려면 해당 -u 인수를 사용해야합니다.

import os 
import pickle 
import subprocess 
from subprocess import PIPE 
import struct 
import builtins 
def call_thru_stream(stream,funcname,*args,**kwargs): 
    """Used for calling a function through a stream and no return value is required. It is assumed 
    the receiving program is in the state where it is expecting a function.""" 
    transmit_object(stream,(funcname,args,kwargs)) 


def function_thru_stream(in_stream,out_stream,funcname,*args,**kwargs): 
    """Used for calling a function through a stream where a return value is required. It is assumed 
    the receiving program is in the state where it is expecting a function.""" 
    transmit_object(in_stream,(funcname,args,kwargs)) 
    return receive_object(out_stream) 

#--------------------- Object layer ------------------------------------------------------------ 

def transmit_object(stream,obj): 
    """Transmits an object through a binary stream""" 
    data=pickle.dumps(obj,2)#Uses pickle version 2 for compatibility with 2x 
    transmit_atom(stream,data) 


def receive_object(stream): 
    """Receive an object through a binary stream""" 
    atom=receive_atom(stream) 
    return pickle.loads(atom) 

#--------------------- Atom layer -------------------------------------------------------------- 
def transmit_atom(stream, atom_bytes): 
    """Used for transmitting a some bytes which should be treated as an atom through 
    a stream. An integer indicating the size of the atom is appended to the start.""" 
    header=struct.pack("=L",len(atom_bytes)) 
    stream.write(header) 
    stream.write(atom_bytes) 
    stream.flush() 


def receive_atom(stream): 
    """Read an atom from a binary stream and return the bytes.""" 
    input_len=stream.read(4) 
    l=struct.unpack("=L",input_len)[0] 
    return stream.read(l) 
관련 문제