2009-03-23 7 views
2

Perl 스크립트에서 rsync 프로세스에 의해 생성 된 모든 진행 메시지를 캡처하고 싶습니다. 특정 상황에서 이것이 작동하지 않습니다. 내가 bash 쉘 내에서이 작업을 실행하면Perl에서 rsync 진행 메시지를 어떻게 캡처 할 수 있습니까?

rsync -aL --verbose --progress --bwlimit=100 \ 
    --include-from=/tmp/78hJ2eDCs1 \ 
    --include '*/' --exclude '*' \ 
    /srcdir/* \ 
    hostname:/target/ 2>&1 

것은, 나는 이런 식으로 뭔가를 볼 수 있습니다 : 여기

은 내가 사용하는 전형적인 rsync를 명령 행의

Building file list ... 
1600 files... 
1700 files... 
and so on 

나는 같은 명령을 시도하는 경우 Perl 내에서 "건물 파일 목록"출력이 정상적으로 표시되지만 상태는 업데이트되지 않습니다. 여기에 내가

my $pid = open(OUTPUT, "$cmd |") or die "Couldn't fork: $!\n"; 

my $ch; 
while(read(OUTPUT, $ch, 1)==1) 
{ 
    print $ch; 
} 
close(OUTPUT); 

내 생각은 rsync를 하나가 일반적인 콘솔없는 출력 핸들을 감지, 아니면 캡처 아니에요 몇 가지 특이한 방식으로 출력되는 점이다 캡처를 테스트하는 방법입니다. 그러나, 심지어 odder를 만드는 것은 --include와 --exclude 필터를 생략하면 상태 메시지를 제대로 캡처 할 수 있다는 것입니다.

무슨 일이 일어나는가에 대한 단서가 있습니까?

+0

두 답변이 이미 제공된 후에 rsync가 출력을 버퍼링하기 위해 수행하는 작업이라고 추측합니다. 결국 출력을 모두 얻었습니까? –

답변

3

솔루션은 간단했다 밝혀졌습니다. Paul Tomblin과 DSM에게 아이디어를 주신 것에 감사드립니다.

+0

웃겨, $ | 및 -> autoflush가 동등한 것이 었습니다. 그래서 나는 그것을 제안했습니다. –

+0

나는 autoflush가 OUTPUT 핸들에 영향을 미쳤다고 생각한다. $ | STDOUT 스크립트에서 작동합니까? 즉, 어떻게 든 출력을 비우지 못하게 되었습니까? –

4

파이프의 출력을 버퍼링합니까? 그렇다면 OUTPUT 핸들을 연 후 OUTPUT-> autoflush (1)로 버퍼링을 해제하면 작업을 수행 할 수 있습니다.

+0

나는 그것을 쓸모 없게하려고 시도했다. - 이상한 점은 --include/exclude 옵션을 사용하지 않으면 모든 출력을 캡처 할 수 있다는 것이다. –

4

PTY를 모방 한 Expect.pm을 사용하면 찾고자하는 결과를 얻을 수 있습니다.

실패한 경우 --stats 또는 --progress 옵션을 사용해보세요. 난 그냥 내가 아직도 내가 몇 가지 rsync를 옵션이 아닌 다른 사람과 문제를 관찰하는 방법에 의해 의아해하고 있습니다 $| = 1;

내 스크립트에서 IO를 버퍼 해제했다 -

+0

Expect에서 출력물을 반복적으로 먹을 수는 없지만 의사 TTY를 모방 한 아이디어는 유익한 것으로 입증 될 수 있습니다. –

+0

아니, IO :: Pty :: Easy를 사용해 보았는데 정확한 동작을 보았습니다. –

0

또한 IPC :: Run을 사용하고 stdout/stderr에 대한 데이터 콜백을 원할 수도 있습니다.

0

Suffering from Buffering?은 지금까지 발견 한 버퍼링 효과에 대한 가장 좋은 설명입니다. 글을 읽고 이해할 가치가 있습니다.

버퍼링이 이유 때문에 존재한다는 것을 잊지 마세요. 가능한 모든 문제에 대해 버퍼링을 끄지 마십시오.

관련 문제