programing

실행 후 PHP StdErr()

css3 2023. 10. 2. 15:22

실행 후 PHP StdErr()

PHP에서 exec()을 사용하여 명령을 실행하고 있으며, URL이 성공하면 반환됩니다.

$url = exec('report');

하지만 혹시 문제가 생겼다면 stderr을 확인하고 싶습니다.제가 그 스트림을 어떻게 읽을까요?php://stderr을 사용하고 싶은데 사용법을 잘 모르겠어요.

명령을 실행하고 둘 다 얻으려면stderr그리고.stdout, "merged"이 아닌 솔루션을 사용할 수 있습니다. 이 솔루션은 실행 중인 명령어에 대한 높은 수준의 제어 기능을 제공합니다. 여기에는 파이프를 연결하는 방법도 포함됩니다.stdin/stdout/stderr.

여기 예가 있습니다. 셸 스크립트가 있다고 생각해 봅시다.test.sh, 두 사람 모두에게 글을 쓰는 겁니다stderr그리고.stdout:

#!/bin/bash

echo 'this is on stdout';
echo 'this is on stdout too';

echo 'this is on stderr' >&2;
echo 'this is on stderr too' >&2;

자, PHP를 코드화해 봅시다.temp.php-- 먼저 i/o 디스크립터를 초기화합니다.

$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin
   1 => array("pipe", "w"),  // stdout
   2 => array("pipe", "w"),  // stderr
);

그리고 나서, 그 다음에, 그 다음에,test.sh명령어를 사용하여 현재 디렉토리에서 i/o는 from/to여야 한다고 말합니다.$pipes:

$process = proc_open('./test.sh', $descriptorspec, $pipes, dirname(__FILE__), null);

이제 두 개의 출력 파이프에서 읽을 수 있습니다.

$stdout = stream_get_contents($pipes[1]);
fclose($pipes[1]);

$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);

그리고 이 두 변수의 내용을 출력하면 다음과 같습니다.

echo "stdout : \n";
var_dump($stdout);

echo "stderr :\n";
var_dump($stderr);

다음과 같은 출력을 얻을 수 있습니다.temp.php스크립트:

$ php ./temp.php
stdout :
string(40) "this is on stdout
this is on stdout too
"
stderr :
string(40) "this is on stderr
this is on stderr too
"

도움이 될만한 작은 기능:

function my_shell_exec($cmd, &$stdout=null, &$stderr=null) {
    $proc = proc_open($cmd,[
        1 => ['pipe','w'],
        2 => ['pipe','w'],
    ],$pipes);
    $stdout = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    $stderr = stream_get_contents($pipes[2]);
    fclose($pipes[2]);
    return proc_close($proc);
}

종료 코드는 반환되며 STDOUT 및 STDERR은 필요한 경우 참조 파라미터입니다.

그런 일을 하는 짧은 방법은exec종료 코드(명령의 상태)를 반환하는 것입니다.

존재하지 않는 디렉토리를 나열하려고 합니다./non-dir/

exec('ls /non-dir/', $out, $retval);
var_dump($retval);

산출량

ls: '/non-dir/'에 액세스할 수 없습니다. 해당 파일이나 디렉토리가 없습니다.
int(2)

일반적으로 유닉스 기반 시스템에서 대부분의 성공적인 상태 코드는 (0)이므로 다음을 확인할 수 있습니다.$retval명령의 상태를 알 수 있습니다.

잘못된 경로를 나열하는 것에서 오류를 제거하다ls: cannot access '/non-dir/': No such file or directorystderr을 null로 리디렉션할 수 있습니다.

exec('ls /non-dir/ 2>/dev/null', $out, $retval);
var_dump($retval);

출력:

int(2)

또한 오류 문자열을 사용하기 위해 필요한 경우 stderrstdout으로 리디렉션할 수 있습니다.

exec('ls /non-dir/ 2>&1', $out, $retval);
print_r($out);
var_dump($retval);

이렇게 하면 다음이 출력됩니다.

Array
(
    [0] => ls: cannot access '/non-dir/': No such file or directory
)
int(2)

병합되지 않은 stdout/stderr를 얻는 또 다른 방법.

$pp_name = "/tmp/pp_test";
@unlink($pp_name);
posix_mkfifo($pp_name, 0777);
$pp = fopen($pp_name, "r+");
stream_set_blocking($pp, FALSE);
exec("wget -O - http://www.youtube.com 2>$pp_name", $r_stdout);
$r_stderr = stream_get_contents($pp);
var_dump($r_stderr);
fclose($pp);
unlink($pp_name);

stdout을 무시하고 stderr만 얻으려면 다음을 시도해 볼 수 있습니다.

exec("wget -O - http://www.youtube.com 2>&1 >/dev/null", $r_stderr);
exec("{$command} 2>&1"
    ,$output
    ,$exitCode
    );
  • 2>&1은 stderr을 stdout으로 리디렉션하여 일관된 성공/실패 동작을 수행합니다.

  • $exitCode$명령 완료 상태를 결정합니다.

  • $output $exitCode와 관련된 모든 출력을 포함합니다.

약간 못생겼지만 충분히 좋아요.stderr을 임시 파일에 넣고 다시 읽습니다.

$tmp = tempnam("/tmp", "ERR_");
exec('report 2> ' . escapeshellarg($tmp), $stdout, $retcode);
$stderr = file_get_contents($tmp);
unlink($tmp);
if ($retcode == 0)
{
    // good
    $url = $stdout[0];
} else {
    // bad
    error_log("FAIL: $stderr");
}

언급URL : https://stackoverflow.com/questions/2320608/php-stderr-after-exec