2012-11-29 2 views
4

Perl 스크립트를 호출하는 방법을 알려주는이 사이트에서 질문을 찾았습니다. Python. 이것은 완벽하게 작동파이썬에서 Perl 스크립트를 호출하여 값을 계속 반환합니다.

pipe = subprocess.Popen(["perl", "./Perl_Script.pl", param], stdout=subprocess.PIPE) 
result = pipe.stdout.read() 

하지만, 유일한 문제는 펄 스크립트를 실행하는 데 몇 분 정도 걸립니다이다 : 나는 현재이를 달성하기 위해 다음 코드 줄을 사용하고 있습니다. Perl 스크립트가 끝나면 간단한 print 문을 사용하여 파이썬으로 돌아가려면 결과 인 Python에서 변수으로 설정해야합니다.

Perl 스크립트에 몇 초마다 Python으로 연속적으로 반환 될 수있는 print 문을 몇 초 동안 포함하고 마지막에 긴 목록을 반환하는 대신 print 문을 더 포함 할 수있는 방법이 있습니까?

궁극적으로 내가하고있는 일은 Perl 스크립트를 사용하여 데이터 포인트를 얻은 다음 파이썬으로 다시 보내어 아이 다이어그램을 그립니다. 펄 스크립트가 끝날 때 아이 다이어그램을 그리는 데 몇 분이 걸리는 대신 파이썬에 데이터의 세그먼트를 연속적으로 반환하여 매 플롯이 몇 초마다 업데이트되도록하고 싶습니다.

+0

perl 스크립트의 중간 단계에서 간단하게 인쇄 해 보았습니까? 나는 그 질문이 무엇인지 모르겠다. –

+0

예.하지만 python 변수 _result_는 perl 스크립트 실행이 완료 될 때까지 업데이트되지 않습니다. 그리고 예, 나는 perl 스크립트 전체에 더 많은 print 문을 넣을 수 있습니다. 그리고 이것들은 반환됩니다. 그러나 perl 스크립트가 끝나면 모두 반환됩니다. – dmranck

+0

파이프로 밀어 넣을 때 버퍼링을 끄는 것과 파이프 입력을 버퍼링하지 않도록하는 것에 대한 대답이 있습니다. 둘 다해야합니다. –

답변

1

당신은 두 가지가 필요합니다 : 파이썬 공간에서 한 번에 한 줄을 읽으려면 펄에서 한 번에 선을 방출 할 수 있습니다. 첫 번째는 당신이 판독 된 데이터를 제공, 부착 공정에서 수신 된 텍스트의 라인 (또는 EOF)까지

while True: 
    result = pipe.stdout.readline() 
    if not result: 
    break 
    # do something with result 

같은 루프와 readline 블록을 달성 할 수있다. 각 데이터 덩어리가 그 자체의 줄에 있으면, 그것은 작동해야합니다.

그러나 Perl 스크립트를 수정하지 않고이 코드를 실행하면 Perl 스크립트 실행이 끝날 때까지는 아무런 결과도 얻을 수 없습니다. 이는 Perl 블록 버퍼가 기본적으로 파이프로 출력되기 때문입니다. 당신은 당신이 인쇄되는 범위에서 전역 변수를 변경하여 더 자주 버퍼를 플러시를 알 수 있습니다 :

use English qw(-no_match_vars); 
local $OUTPUT_AUTOFLUSH = 1; 
print ...; 

http://perl.plover.com/FAQs/Buffering.htmlhttp://perldoc.perl.org/perlvar.html를 참조하십시오.

+0

감사합니다. 정확히 내가 필요로하는 것. – dmranck

2

기본 UNIX stdio 버퍼는 8k 이상입니다. 8k보다 작게 쓰면 버퍼가 플러시되기 전에 프로그램이 종료 될 때까지 기다리게됩니다.

출력을 버퍼링하지 않도록 Perl 프로그램에 지시하고, 파이썬이 파이프를 통해 입력을 버퍼링하지 않도록 지시합니다. 펄 프로그램되지 않은 버퍼 STDOUT에

$| = 1;

.

+0

기본적으로 텍스트 버퍼를 처리하는 유닉스 도구가 아닌가? 'cat -'은 그 행동을 표시합니다 (각 줄은 즉시 플러시됩니다). – goncalopp

+1

read() 및 write() 시스템 호출을 직접 사용하는 경우 버퍼가 해제 된 출력을 수행합니다. stdio 라이브러리를 사용한다면 stdio가 읽기/쓰기의 상단에 버퍼링을 구현하기 때문에 버퍼링 된 IO를 사용하고 있습니다. stdio 함수를 사용하고 싶지만 버퍼링을 사용하지 않으려면 함수 호출을 사용하여 버퍼 크기를 0으로 설정해야합니다. cat이 구현 된 방법을 모르지만 stdio는 버퍼링 된 것과 같지 않지만 작동하지 않습니다. 몇 가지 라인 중심 기능을 제공합니다. 그러나 한 줄은 다음에 줄 바꿈 문자가 나타날 때까지 한 묶음의 텍스트로 정의됩니다 (기본값은 UNIX에서는 \ n, Windows에서는 \ r \ n입니다). –

+0

파이프에 대한 Perl의 STDOUT은 기본적으로 블록 버퍼입니다. http://perldoc.perl.org/perlvar.html의'$ OUTPUT_AUTOFLUSH'를보십시오. – darch

1

pipe.stdout.read()는 전체 스트림을 읽으려고하므로 perl이 끝날 때까지 차단됩니다. 이 시도 :

line=' ' 
while line: 
    line = pipe.stdout.readline() 
    print line, 
+1

사실이지만 불완전합니다. 이것은 사용자의 버퍼 문제를 해결하지 않고는 도움이되지 않습니다. (http://perl.plover.com/FAQs/Buffering.html 참조) – darch

+0

'Buffer Suffering'은 밈이어야합니다. –

관련 문제