2017-12-05 8 views
2

이것이 가능한지 모르겠지만 소켓을 통한 명령 출력을 보내려고하므로 명령이 실행되는 동안 클라이언트와 서버 컴퓨터 모두에 표시됩니다. 백틱을 사용하려고하면 오랜 시간이 걸리는 명령을 실행할 때 명령이 완료 될 때까지 출력이 변수에 저장되지 않습니다.실시간 백틱 출력 처리

질문 : 다른 프로세스를 생성하고 변수를 "감시"한다고 말하면 라인별로 출력을 검사하는 방법이 있습니까?

편집 :이 내가 출력 명령이 완료되기 전에 표시하고자하는 개방

open DATA, "pause |" or die "Failed: $!"; 
while(defined(my $line = <DATA>)){ 
    chomp($line); 
    print "$line\n"; 
} 

으로 시도하는 것이다.

+0

소켓이 백틱과 어떤 관련이 있는지 이해할 수 없습니다. 프로그램의 STDOUT을 읽거나 소켓을 읽으려고합니까? – ikegami

+0

줄 바꿈을 stdout에 추가하자마자 stdout을 비동기 적으로 읽고 출력 할 수 있기를 원합니다. 소켓 부분은 중요하지 않습니다. – TheAschr

+0

1 개 이상의 입력 **에서 비동기 적으로 읽으려면 0 개 이상의 클라이언트에게 이벤트를 보내려면 * 비 차단 IO *로 작업하고 모든 IO를 동시에 지정하기 위해'select' 명령을 사용해야합니다 ... –

답변

6

당신은 올바른 접근 방식을 가지고 있습니다. STDOUT 터미널 ("광고 버퍼링") 인 경우 개행 만나면

my @cmd = ('perl', '-e', '$|=1; for (1..5) { print "$_\n"; sleep 1; }'); 

open(my $pipe, '-|', @cmd) 
    or die("Can't launch child: $!\n"); 

while (defined(my $line = <$pipe>)) { 
    chomp($line); 
    print "<$line>\n"; 
} 

STDOUT 서면, 대부분의 프로그램들은 출력 플러시. STDOUT이 터미널이 아닌 경우 ("블록 버퍼링") 대부분의 프로그램은 4KiB 또는 8KiB의 청크 출력을 차단합니다. 그래서 위의 예에서 하위 프로그램에 $|=1;을 사용해야했습니다.

설명대로 작동하는 프로그램은 파이프 대신 의사 터미널을 사용하여 회선 버퍼링을 사용하여 속일 수 있습니다.

my @cmd = ('unbuffer', 'perl', '-e', 'for (1..5) { print "$_\n"; sleep 1; }'); 

open(my $pipe, '-|', @cmd) 
    or die("Can't launch child: $!\n"); 

while (defined(my $line = <$pipe>)) { 
    chomp($line); 
    print "<$line>\n"; 
} 

IPC::Run은 가상 터미널을 생성하는 고유 한 방법을 제공합니다.

use IPC::Run qw(run); 

my @cmd = ('perl', '-e', 'for (1..5) { print "$_\n"; sleep 1; }'); 

my $buf = ''; 
run(\@cmd, '>pty>', sub { 
    $buf .= $_[0]; 
    while ($buf =~ s/^(.*)\r\n//) { 
     print "<$1>\n"; 
    } 
}); 
+0

감사합니다. 'unbuffer'. 전에만 알았 으면 ...하지만 꼭 설치해야합니다, 그렇죠? 내 우분투는'expect' 패키지의 일부라고 말한다. – PerlDuck

+0

파일 핸들로'DATA'를 사용하면 효과가 있다고 생각합니까? 영업 인은 그것을 사용하지만 의심 스럽습니다. – PerlDuck

+1

@PerlDuck 예, 'unbuffer'를 설치해야합니다. 그래서 IPC :: Run에 내장 메소드가 있습니다 (예제를 추가했습니다). /// 예, '데이터'를 다시 열 수 있습니다. 물론,'DATA'는 이미 의미가 있기 때문에 사용하는 것이 좋지 않습니다. 왜냐하면 그것은 어휘 적 변수가 아닌 전역 변수이기 때문입니다. – ikegami