2010-02-23 30 views
43

PHP'de exec() ile bir komut yürütüyorum ve bir URL başarılı olursa döner;PHP StdErr sonra Exec()

Ancak, bir şeyler yanlış giderse stderr'i kontrol etmek istiyorum. Akışı nasıl okurum? php: // stderr kullanmak istiyorum ama nasıl kullanacağımı bilmiyorum.

+0

Symfony/Process bileşenini kullanmanızı tavsiye edeceğim. –

cevap

65

muhtemelen idam edilecek komuta üzerinde kontrol büyük bir düzeyi sağlar proc_open kullanmak istiyorum, bir çözüm, bir komutu çalıştırmak ve stderr ve stdout hem değil "birleştirilmiş" almak istiyorsanız - Bir bakıma dahil stdin/stdout/stderr numaralı boruya.


Ve burada bir örnek: temp.php yılında, kod Biraz PHP edelim, Şimdi

#!/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; 


: en ikimiz de stderr ve stdout yazar, hangi test.sh yılında, bu kabuk senaryomuz var düşünelim

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


: - ilk olarak, i/o tanımlayıcıları başlatmakVe o zaman, geçerli dizinde, bu tanımlayıcılar kullanarak ve i/o gelen/$pipes olmalıdır söyleyerek test.sh komutu çalıştırın: Şimdi iki çıkış borusundan okuyabilir

$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]); 


Ve biz çıkışı bu iki değişkenin içeriği ise:

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

echo "stderr :\n"; 
var_dump($stderr); 
senaryoyu çalıştırırken


Biz şu çıktıyı almak:

$ 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 
" 


Umut bu yardımcı olur :-)

+3

Bunu kullanırken, temizlik için hepiniz bittiğinde proc_close kullandığınızdan emin olun. –

+0

Neden bir işlem varlığında sonuç yönlendiriyorsunuz? –

+3

@BriceFavre Bir süreç varyasyonuna koyar, böylece daha sonra proc_close ile kapatabilir, bu da geri dönüş kodunun çıktığı süreci geri getirir. '$ returnCode = proc_close ($ process); Windows ortamında bulunan –

6

birleştirilmemiş stdout/stderr'yi almak için başka bir yol. Eğer stdout'u göz ardı edip sadece stderr almak istiyorsanız

$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); 

, bu deneyebilirsiniz: yararlı olabilir

exec("wget -O - http://www.youtube.com 2>&1 >/dev/null", $r_stderr); 
30

Biraz işlevi: çıkış kodu döndürülür

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); 
} 

İhtiyacınız varsa STDOUT ve STDERR referans paramlarıdır.

+2

Güzel ve basit, mükemmel çalışıyor. Gönderdiğiniz için teşekkürler! –