[PHP] 프로세스를 실행시키면서 STDOUT, STDERR를 문자열 변수에 담기 (open_proc, descriptor_spec, stream_get_contents)
PHP 2014. 8. 19. 14:27일반적인 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;
}
[참조]