2012-05-15 2 views
2

안녕하세요 내가 파이썬 서브 프로세스 모듈에 문제가 차단 될 때 공정 (예 : 자녀의 표준 입력, 표준 출력)파이썬 <p =는 popen ([ "명령", 표준 출력 = PIPE)> p.stdout.read는 (-1)</p> <p>제가 아이 작용하려는

이것은 어린이 프로그램의 코드

1 #include <stdio.h> 
    2 
    3 int main(){ 
    4   char buf[1024]; 
    5   printf("asdfsadfasff\n"); 
    6   scanf("%s",buf); 
    7   printf("%s\n",buf); 
    8 } 

이 코드는 매우 간단합니다, 문자열을 인쇄 입력을 기다린 인쇄 입력 문자열

와 다음, 파이썬 코드입니다. 이 경우

1 #!/usr/bin/python 
    2 from subprocess import * 
    3 
    4 fd = Popen(["./random"],stdin=PIPE,stdout=PIPE) 
    5 print "pid = %d"%(fd.pid) # print pid 
    6 result = "" 
    7 result = fd.stdout.read(-1) # read 
    8 print result 
    9 fd.stdin.write("write write write!!!\n") 
10 result = fd.stdout.read(-1) 
11 print result 

아래, 나는이 프로그램이 잘 작동합니다 기대하지만, 라인 7 (fd.stdout.read이 (-1) 차단 결코 내가 함수의 PARAM을 읽을 변경

작동되지 않았다 (읽기 (1), read (1), read(), read (1024))하지만 모두 작동하지 않습니다.

그러나 처음에는 stdin에 문자열을 줄 때 프로그램이 작동했습니다.

나는이 문제에 대한 해결책이 있습니까 이것은 단지 내 opnion

입니다 ... 프로그램이 종료 될 때 자녀의 표준 출력 버퍼가 입력되지 않았습니다 생각하십니까?

편집 1. 내가 처음 인쇄 문자열 인 프로그램을 실행, 및 "sudo를 쓰에" 로 사용자의 입력을 기다릴 때 이 내가

내가 이해할 수없는 기대 것을 잘 작동 왜이 경우 작업도

1 from subprocess import * 
    2 
    3 fd = Popen(["sudo","su"],stdin=PIPE,stdout=PIPE) 
    4 
    5 print fd.stdout.read(-1) 
    6 print fd.stdin.write("asdfasdfas\n") 
+0

첫 번째'printf' 후에'flush (stdout);하면 어떻게 될까요? – mgilson

+0

분명히 C 함수는'fflush'입니다 ... 죄송합니다. C가 조금 녹슬 었습니다. – mgilson

+0

1 #include 3 int main() { 4 char buf [10]; 5 printf ("asdfsadfasff \ n"); 6 fflush (stdout); 7 scanf ("% s", buf); 8 printf ("% s \ n", buf); 9} fflush를 추가했지만 결과가 변경되지 않았으므로 fflush를 시간 초과하는 데 실수가 있습니까? –

답변

5

자식 프로세스 ./randomstdio을 사용합니다. 프로세스의 stdout이 tty 장치가 아닌 경우 기본적으로 "전체 버퍼링"대신 "전체 버퍼링"을 수행합니다. 파이썬은 tty 장치가 아닌 파이프를 통해 프로세스를 실행하기 때문에 프로그램은 출력을 버퍼링하고 scanf 호출시 인쇄하지 않습니다. 버퍼가 가득 차면 버퍼가 플러시되고 (stdout에 기록됨) (a) 만 버퍼링됩니다. (b) fflush 호출로 명시 적으로 플러시 된 경우; 또는 (c) 프로그램 종료시.

fflush 명시 적 호출을 수행하도록 자식 프로세스를 수정하거나 Python의 의사 태그 (예 : pexpect 또는 sh)를 사용할 수 있습니다. (기본적으로 sh 모듈은 출력용으로 pty를 사용하지만, 보통은 충분합니다.) 또는, 실행중인 프로그램이 "대화식으로 보입니다"(실제로는 완전히 예측 가능) 같은 경우, 다음 물론 당신은 모든 표준 출력 입력이 함께 혼합거야하지만

fd = Popen(["./random"], stdin=PIPE, stdout=PIPE) 
result = fd.communicate("write write write!!!\n")[0] 

을, (이 특정 경우)가 인쇄 두 줄을 분리 할 필요가 : 알려진 입력 순서 사전에 제공하여 실행합니다.

+0

고마워 하지만 내 경우에는 scanf는 부모에서 첫 번째 출력 문자열을 얻기 전에 실행되지 않습니다. (내 문제 => 프로그램은 시드를 무작위로 만들고이 시드를 사용하여 임의의 숫자 (20 정수)를 얻습니다. 그것을 인쇄하십시오. 몇 가지 번호를 얻으려면 기다렸다가 다음 입력을 입력하고 생성 된 시드 번호가 동일합니다)이 경우에는, 나는 전체 버퍼링 시스템이 문제를 해결할 수있는 이해 ...... ...... –

+0

변경할 수있는 깃발이나 뭔가가 있습니까 셸의 stdio 버퍼 시스템 황소 버퍼링 라인 버퍼링? –

+0

일반적으로 다른 프로그램의 버퍼링 동작을 변경하는 방법은 없습니다. 그러나'pexpect' (응답의 링크 참조)를 사용하면,'pexpect'는 일반적인 대화 형 사용자 명령처럼 pseudo-tty를 열기 때문에 사용자와 대화하고 있다고 가정하는 프로그램과 상호 작용할 수 있습니다 창문. 즉, 어떤 방식 으로든 하위 프로세스를 변경하지 않고 실제 대화식 세션에서 실행하는 것입니다. – torek