2012-10-16 3 views
2

브라우저에서 호출 할 때 항상 "멈춤"하는 쉘 스크립트를 호출하는 간단한 perl 스크립트가 있습니다. 나는 20 초 후에 단순히 시간을 강제로 풀고 싶다. 커맨드 라인에서 실행할 때 아무런 문제가 없습니다. 그러나 브라우저에서 스크립트를 실행하면 스크립트가 실행되지만로드가 완료되지 않습니다. 그래서 나는 그 페이지에 결과를 얻지 못한다. 명령 줄에서 프로세스를 종료하면 브라우저가로드를 완료하고 브라우저에 내용이 표시됩니다.perl 알람이 예상대로 작동하지 않습니다.

나는 많은 연구를했으며 쉘 스크립트가 여전히 표준 출력에 대한 열린 파일 핸들을 가지고 있기 때문에 웹 서버가 쉘 스크립트가 완료 될 때까지 기다리는 것 같습니다.

여기 내 코드입니다.

#!/usr/bin/perl 

use strict; 
use warnings; 

use CGI; 

my $q = new CGI; 

print $q->header; 

my $timeout = 10; 
my $pid = fork; 

if (defined $pid) { 
    if ($pid) { 

     # this is the parent process 
     local $SIG{ALRM} = sub { die "TIMEOUT" }; 

     alarm 10; 

     # wait until child returns or timeout occurs  
     eval { 
      waitpid($pid, 0); 
     }; 

     alarm 0; 

     if ([email protected] && [email protected] =~ m/TIMEOUT/) { 
      # timeout, kill the child process 
      kill 9, $pid; 
     } 
    } 
    else { 
     # this is the child process 
     # this call will never return. Note the use of exec instead of system 
     exec "/opt/bea/domains/fsa/scripts/start.sh"; 
    } 
} 
else { 
    die "Could not fork."; 
} 

특정 시간이 지난 후에는 쉘 스크립트의 상태에 관계없이 페이지로드가 완료되도록하려면 어떻게해야합니까?

+1

당신은 정말 – Ralgha

+0

확인 ... 여기에 질문을하지 않았다, 내가 마지막에 질문을 :) – user1750930

+0

는에 가정 스크립트입니다 브라우저에 아무것도 출력하지 않으십니까? – ikegami

답변

0

스크립트가 끝난 후에도 웹 서버는 생성 된 모든 자식이 완료 될 때까지 기다리는 중입니다. 가장 좋은 방법은 setsid으로 별도의 프로세스 그룹을 생성하는 것입니다. 또는 "double fork trick"을 시도해 볼 수도 있습니다. 여기서 포크와 아이에서 다시 포크로 이동합니다. 그 후 첫 번째 자녀가 종료되고 두 번째 자녀가 init 인 경우 자녀가됩니다. 또한 (두 경우 모두) 아이에 당신이 있는지 확인하십시오

close STDIN; 
close STDOUT; 
close STDERR;