일반적인 exec() 함수 등을 이용해서 프로세스를 실행시킬 경우 반환값이나 call by reference 변수 등을 통해 STDOUT 내용은 받아올 수 있지만, STDERR는 제어가 안됨.

사실 STDERR를 어케 해볼려고 만든 함수.


프로세스를 실행하면서 각 표준 I/O 스트림에 파이프를 박고, 실행완료 후 스트림을 쪽 빨아오는 방식.



/*
$cmd 명령어를 실행하고 결과값을 배열에 담아 반환.
return = array(
    'stdout'   => STDOUT 출력내용,
    'stderr'   => STDERR 출력내용,
    'exitcode' => 프로세스 exitcode
)

프로세스 실행 실패시 null 반환.
*/
function exe($cmd)
{
    $err_file = tempnam(sys_get_temp_dir(), 'err');

    $DescriptorSpec = array(
        // STDIN
        0 => array('pipe', 'r'),
        // STDOUT
        1 => array('pipe', 'w'),
        // STDERR
        // Windows에서 여길 pipe로 지정하면 스트림을 읽어올 때 무한 blocking 에 빠지므로 부득이 파일로 지정함
        2 => array('file', $err_file, 'w')
    );
    // 스트림에 연결할 파이프
    $pipes = array();
    // working directory
    $cwd = null;
    // 환경변수
    $env = null;
    // Windows 전용 기타옵션
    $other_options = array(
        // $cmd를 cmd.exe로 우회실행.
        // bypass_shell을 true로 해야 $cmd에 공백문자가 있어도 제대로 실행됨.
        'bypass_shell' => true
    );

    $proc = proc_open($cmd, $DescriptorSpec, $pipes, $cwd, $env, $other_options);
    if (is_resource($proc) === false) return null;

    $result = array(
        'stdout' => rtrim(stream_get_contents($pipes[1])),
        'stderr' => rtrim(file_get_contents($err_file))
    );
    $result['exitcode'] = proc_close($proc);
    unlink($err_file);

    return $result;
}



[참조]

http://www.php.net/proc_open














Posted by bloodguy
,