복붙노트

PHP 독서 shell_exec 라이브 출력

PHP

PHP 독서 shell_exec 라이브 출력

나는 PHP와 shell_exec을 리눅스 서버에서 실험하고있다. 사용하기에 정말 멋진 기능이며 지금까지 정말 즐겁습니다. 명령이 실행되는 동안 진행중인 실시간 출력을 보는 방법이 있습니까?

예를 들어 ping stackoverflow.com을 실행 한 경우 대상 주소를 ping하는 동안 핑이 발생할 때마다 PHP로 결과를 표시합니까? 그게 가능하니?

실행중인 버퍼의 실시간 업데이트를보고 싶습니다. 어쩌면 가능한 일은 아니지만 확실히 좋을 것입니다.

이것은 내가 시도하는 코드이며, 명령을 마친 후에는 항상 결과를 표시하기 위해 노력했습니다.

<?php

  $cmd = 'ping -c 10 127.0.0.1';

  $output = shell_exec($cmd);

  echo "<pre>$output</pre>";

?>

에코 부분을 루프에 넣으려고 시도했지만 여전히 운이 없습니다. 누구나 명령이 완료 될 때까지 기다리지 않고 화면에 라이브 출력을 보여줄 수있는 제안이 있습니까?

exec, shell_exec, system 및 passthru를 시도했습니다. 모든 사람이 끝나면 내용을 표시합니다. 잘못된 구문을 사용하지 않거나 제대로 루프를 설정하지 않는 한.

해결법

  1. ==============================

    1.프로세스의 출력을 읽으려면 popen ()을 사용하십시오. 스크립트는 프로그램과 병행하여 실행되며, 파일 인 것처럼 출력 / 입력을 읽고 쓰는 방식으로 스크립트와 상호 작용할 수 있습니다.

    프로세스의 출력을 읽으려면 popen ()을 사용하십시오. 스크립트는 프로그램과 병행하여 실행되며, 파일 인 것처럼 출력 / 입력을 읽고 쓰는 방식으로 스크립트와 상호 작용할 수 있습니다.

    그러나 결과를 사용자에게 직접 덤프하려는 경우 추격을 줄이고 패스 스루 ()를 사용할 수 있습니다.

    echo '<pre>';
    passthru($cmd);
    echo '</pre>';
    

    프로그램이 실행될 때 런타임에 출력을 표시하려면 다음을 수행 할 수 있습니다.

    while (@ ob_end_flush()); // end all output buffers if any
    
    $proc = popen($cmd, 'r');
    echo '<pre>';
    while (!feof($proc))
    {
        echo fread($proc, 4096);
        @ flush();
    }
    echo '</pre>';
    

    이 코드는 명령을 실행하고 런타임에 출력을 최종 사용자에게 직접 전달해야합니다.

  2. ==============================

    2.우선, 당신의 스 니펫에 대해 Havenard에게 감사드립니다 - 그것은 많은 도움이되었습니다!

    우선, 당신의 스 니펫에 대해 Havenard에게 감사드립니다 - 그것은 많은 도움이되었습니다!

    내가 발견 한 Havenard 코드의 약간 수정 된 버전.

    <?php
    /**
     * Execute the given command by displaying console output live to the user.
     *  @param  string  cmd          :  command to be executed
     *  @return array   exit_status  :  exit status of the executed command
     *                  output       :  console output of the executed command
     */
    function liveExecuteCommand($cmd)
    {
    
        while (@ ob_end_flush()); // end all output buffers if any
    
        $proc = popen("$cmd 2>&1 ; echo Exit status : $?", 'r');
    
        $live_output     = "";
        $complete_output = "";
    
        while (!feof($proc))
        {
            $live_output     = fread($proc, 4096);
            $complete_output = $complete_output . $live_output;
            echo "$live_output";
            @ flush();
        }
    
        pclose($proc);
    
        // get exit status
        preg_match('/[0-9]+$/', $complete_output, $matches);
    
        // return exit status and intended output
        return array (
                        'exit_status'  => intval($matches[0]),
                        'output'       => str_replace("Exit status : " . $matches[0], '', $complete_output)
                     );
    }
    ?>
    

    샘플 사용법 :

    $result = liveExecuteCommand('ls -la');
    
    if($result['exit_status'] === 0){
       // do something if command execution succeeds
    } else {
        // do something on failure
    }
    
  3. ==============================

    3.의존성을 다운로드하려는 경우 Symfony의 프로세서 구성 요소가이를 수행합니다. popen () 또는 passthru ()를 사용하여 직접 새로 작성하는 것보다이 클리너로 작업 할 수있는 인터페이스를 발견했습니다.

    의존성을 다운로드하려는 경우 Symfony의 프로세서 구성 요소가이를 수행합니다. popen () 또는 passthru ()를 사용하여 직접 새로 작성하는 것보다이 클리너로 작업 할 수있는 인터페이스를 발견했습니다.

    이것은 Symfony 문서에서 제공되었습니다.

    경고로, 나는 PHP와 Nginx가 브라우저에 보내기 전에 출력을 버퍼링하는 데 몇 가지 문제를 겪었다. PHP에서 출력 버퍼링을 비활성화하려면 php.ini : output_buffering = off에서 해제하십시오. Nginx에서이 기능을 비활성화하는 방법이 있지만 PHP를 사용하여 테스트를 거쳐 번거 로움을 피할 수있었습니다.

    나는 Gitlab에서 이것에 대한 완전한 예를 든다 : https://gitlab.com/hpierce1102/web-shell-output-streaming

  4. from https://stackoverflow.com/questions/20107147/php-reading-shell-exec-live-output by cc-by-sa and MIT license