>

foreach를 사용하여 배열의 각 멤버를 사용하여 wget 요청을 실행하는 명령 행 PHP 스크립트가 있습니다. 이 wget 요청은 때때로 시간이 오래 걸릴 수 있으므로 스크립트가 예를 들어 15 초가 지난 경우 스크립트 종료에 대한 시간 초과를 설정하고 싶습니다. PHP 안전 모드를 비활성화하고 스크립트 초기에 set_time_limit (15)를 시도했지만 무한정 계속됩니다.업데이트 :Dor에게 감사의 말을 전합니다. set_time_limit ()는 system () 호출을 존중하지 않기 때문입니다.

따라서 15 초 후에 스크립트를 죽이는 다른 방법을 찾으려고 노력했습니다. 그러나 스크립트가 동시에 wget 요청을하는 동안 스크립트가 실행중인 시간을 확인할 수 있는지 확실하지 않습니다 (do while 루프가 작동하지 않음). 어쩌면 타이머로 프로세스를 포크하고 정해진 시간이 지나면 부모를 죽 이도록 설정할 수 있습니까?

팁 감사합니다!

업데이트 : 아래는 내 관련 코드입니다. $url은 명령 행에서 전달되며 여러 URL의 배열입니다 (처음에 이것을 게시하지 않아서 죄송합니다) :

foreach( $url as $key => $value){
    $wget = "wget -r -H -nd -l 999 $value";
    system($wget);
    }

  • 답변 # 1

    "-timeout"과 time ()의 조합을 사용할 수 있습니다. 총 시간을 계산하여 시작하고 스크립트가 실행될 때 --timeout을 낮 춥니 다.

    예 :

    $endtime = time()+15;
    foreach( $url as $key => $value){
      $timeleft = $endtime - time();
      if($timeleft > 0) {
        $wget = "wget -t 1 --timeout $timeleft $otherwgetflags $value";
        print "running $wget<br>";
        system($wget);
      } else {
        print("timed out!");
        exit(0);
      }
    }
    
    

    참고 : -t를 사용하지 않으면 wget은 대기 시간 (초)마다 20 번 시도합니다.

    다음은 proc_open/proc_terminate (@Josh의 제안)를 사용하는 예제 코드입니다 :

    $descriptorspec = array(
       0 => array("pipe", "r"),
       1 => array("pipe", "w"),
       2 => array("pipe", "w")
    );
    $pipes = array();
    $endtime = time()+15;
    foreach( $url as $key => $value){
      $wget = "wget $otherwgetflags $value";
      print "running $wget\n";
      $process = proc_open($wget, $descriptorspec, $pipes);
      if (is_resource($process)) {
        do {
          $timeleft = $endtime - time();
          $read = array($pipes[1]);
          stream_select($read, $write = NULL, $exeptions = NULL, $timeleft, NULL);
          if(!empty($read)) {
            $stdout = fread($pipes[1], 8192);
            print("wget said--$stdout--\n");
          }
        } while(!feof($pipes[1]) && $timeleft > 0);
        if($timeleft <= 0) {
          print("timed out\n");
          proc_terminate($process);
          exit(0);
        }
      } else {
        print("proc_open failed\n");
      }
    }
    
    

  • 답변 # 2

    wget 명령 행 인수 --timeout 를 사용해보십시오.   set_time_limit() 외에 .

    set_time_limit(15) 를 명심하십시오  타임 아웃 카운터를 0에서 다시 시작하므로 루프 내에서 호출하지 마십시오 (귀하의 목적으로).

    man wget 에서

    :

    와이즈 비즈

    수정 :확인 당신이 지금하고있는 것을 봅니다. 아마도 당신이해야 할 일은

    --timeout=seconds

    Set the network timeout to seconds seconds. This is equivalent to specifying --dns-timeout, --connect-timeout, and --read-timeout, all at the same time.

    When interacting with the network, Wget can check for timeout and abort the operation if it takes too long. This prevents anomalies like hanging reads and infinite connects. The only timeout enabled by default is a 900-second read timeout. Setting a timeout to 0 disables it altogether. Unless you know what you are doing, it is best not to change the default time-out settings.

    All timeout-related options accept decimal values, as well as subsecond values. For example, 0.1 seconds is a legal (though unwise) choice of timeout. Subsecond timeouts are useful for checking server response times or for testing network latency.

    대신 proc_open을 사용하는 것입니다. system 를 사용하십시오. wget tskes가 너무 길면 proc_terminate를 호출하여 시간을 확인하는 함수입니다.

  • 답변 # 3

    wget 프로그램의 출력을 파일로 보내면 즉시 반환됩니다.
    참조 :

    와이즈 비즈

    출처 : set_time_limit () @ php.net

  • 답변 # 4

    가장 최선의 방법은 적어도 리눅스 (Ubuntu 17.10)에서 명령 자체에서 죽이기를 처리하는 것이라고 생각합니다. 나를 위해 일한 다른 수단은 없습니다 ... time()  다른 답변에서 효과가 있었지만 출력이 제공되지 않았습니다.

    아래 예에서는 프로세스가 여전히 실행 중인지 확인하는 매직 문자열을 추가합니다.

    Note: The set_time_limit() function and the configuration directive max_execution_time only affect the execution time of the script itself. Any time spent on activity that happens outside the execution of the script such as system calls using system(), stream operations, database queries, etc. is not included when determining the maximum time that the script has been running. This is not true on Windows where the measured time is real.

    보다 오래 실행되는 경우 , 프로세스가 즉시 종료되고 'Timeout!'이라는 메모가 남습니다.

    이와 같이 명령이 시간 초과를 초과하지 않으며 필요한 모든 stdout/stderr을받습니다

    proc_terminate
    
    

    $sec

관련 자료

  • 이전 angular - angular2 - 'name'구성이 기존 경로 'name'과 충돌
  • 다음 gdb - XCode 4 콘솔의 디버그 출력을 로그 파일로 리디렉션