2010-02-23 13 views
43

PHP में मैं exec() के साथ एक कमांड निष्पादित कर रहा हूं, और यदि यह सफल होता है तो यह लौटाता है;एक्सेक के बाद PHP StdErr()

$url = exec('report'); 

हालांकि, मैं, stderr जाँच करना चाहते हैं, तो कुछ गलत हो गया। मैं स्ट्रीम कैसे पढ़ूंगा? मैं php: // stderr का उपयोग करना चाहता हूं, लेकिन मुझे यकीन नहीं है कि इसका उपयोग कैसे करें।

+0

मैं आपको सिम्फनी/प्रोसेस घटक का उपयोग करने की सलाह दूंगा। –

उत्तर

65

आप एक आदेश एक समाधान पर अमल करने, और stderr और stdout दोनों, नहीं "विलय कर दिया" मिलता है, शायद proc_open है, जो आदेश पर नियंत्रण का एक बड़ा स्तर है कि निष्पादित किया जा रहा है प्रदान करता है का उपयोग करने के लिए चाहते हैं - एक तरह से सहित पाइप stdin/stdout/stderr पर।


और यहाँ एक उदाहरण है: temp.php में

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


अब, चलो चलो कोड कुछ पीएचपी,: चलो पर विचार हम जो दोनों stderr और stdout को लिखते हैं test.sh में इस खोल स्क्रिप्ट है, चलो

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


: - पहला, हम आई/ओ वर्णनकर्ता प्रारंभऔर, फिर, test.sh आदेश पर अमल, उन वर्णनकर्ता का उपयोग कर, मौजूदा निर्देशिका में, और कह रही है मैं/हे होना चाहिए से/$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 
" 


आशा इस मदद करता है :-)

+3

इसका उपयोग करते समय, सुनिश्चित करें कि आप सभी सफाई_क्लोज़ का उपयोग करते हैं जब आप सफाई के लिए किए जाते हैं। –

+0

आप एक प्रक्रिया var में परिणाम क्यों रीडायरेक्ट करते हैं? –

+3

@BriceFavre वह इसे एक प्रक्रिया var में रखता है ताकि वह बाद में proc_close के साथ इसे बंद कर सके, जो उस प्रक्रिया को वापस लौटाएगा जिस पर प्रक्रिया समाप्त हो गई है। '$ वापसी कोड = proc_close ($ प्रक्रिया); विंडोज़ evironments में' –

6

एक और तरीका है मर्ज ना किए गए 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); 
30

एक छोटी सी समारोह है कि उपयोगी हो सकता है:

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 संदर्भ पैरा हैं।

+2

अच्छा और सरल, पूरी तरह से काम करता है। पोस्ट करने का शुक्रिया!!! –

संबंधित मुद्दे