2011-04-26 5 views
1

나는 Perl을 사용하여 psexec을 실행하고 콘솔에서 출력을 캡처합니다. 이상한 점은 backticks 명령을 실행할 때마다 출력을 올바르게 캡처한다는 것입니다.자체 자식을 만들고 해당 자식 출력을 리디렉션하는 콘솔 응용 프로그램의 출력을 어떻게 리디렉션 할 수 있습니까?

예를 들어,이 펄 스크립트는 을 작동하고, 나는 많은 다른 구성에 몇 년 동안이를 사용했습니다 :

use strict; 
my @out; 
@out = `psexec \\\\192.168.1.105 -u admin -p pass netstat -a`; 

print @out; 

이 펄 스크립트가 실패하고 안정적으로 psexesvc가에 중단 될 것으로 보인다 원격 시스템 :

use IPC::Open2; 

my($chld_out, $chld_in, $pid); 
$pid = open2($chld_out, $chld_in, 'psexec \\\\192.168.1.105 -u admin -p pass netstat -a'); 

waitpid($pid, 0); 
my $child_exit_status = $? >> 8; 
my $answer = <$chld_out>; 

print "\n\n answer: $answer"; 

저에게 이상한 점은 백틱이 전혀 문제가없는 것 같습니다. 다른 모든 것은 examples in C++ from MSDN을 포함하여 수행합니다.

내 생각에 IPC :: Open2 및 C++ (위 링크)의 예제는 명령 셸 (cmd.exe)에서 STDIN 및 STDOUT을 리디렉션한다는 사실과 관련이 있습니다. 프로세스 (psexec)는 원격 시스템과 통신 할 때 동일한 작업을 수행합니다.

또한 perldocs에서 백틱 작동 방식에 대한 자세한 정보를 찾을 수 있습니까? 나는 Windows에서 "내부"에 가장 관심이 있습니다.

또는 Perl 소스에서 backticks의 내부 동작을 검토 할 수 있습니까? (내가 씹을 수있는 것보다 더 많이 물지 만,이 시점에서는 그럴만 한 가치가 있습니다).

UPDATE : 그래서 아마 누군가가, 좀 더 구체적인 답을 제공 할 수

use IPC::Open2; 

my($chld_out, $chld_in, $pid); 
$pid = open2($chld_out, $chld_in, 'psexec \\\\192.168.1.105 -u admin -p pass netstat -a'); 

my @answer = <$chld_out>; 
print "\n\n answer: @answer"; 

waitpid($pid, 0); 
my $child_exit_status = $? >> 8; 
+1

'waitpid'를 호출하기 전에 출력 ('my $ answer = <$chld_out>')을 읽으려고 했습니까? – Andy

+0

와우, 그게 효과가 있습니다. 왜 나는 몰라! – Mick

답변

2

내가이 창에 어떻게 작동하는지에 대해 거의 알고 있지만 사이에 배관 때 앤디의 제안에 따라, 나는이 작품을 발견 perl에서 프로세스를 처리하려면 원하지 않는 블로킹 및 교착 상태를 피하려면주의해야합니다. perlipc에는 다양한 문제 시나리오에 대한 토론이 있습니다.

예에서 waitpid으로 즉시 호출하면 문제가 발생합니다. 한 가지 가능성은 자식이 출력을 읽을 때까지 자식을 종료 할 수 없으므로 부모가 출력을 읽지 않으므로 모든 것이 중단된다는 것입니다. 또 다른 가능성은 waitpid 호출의 일부로 데이터 스트림의 일부가 종료되어 원격 프로세스에 문제가 발생한다는 것입니다.

어쨌든 waitpid을 호출하기 전에 하위 프로세스의 출력을 읽는 것이 좋습니다.

관련 문제