2010-08-11 14 views
12

मैं उत्पादन सर्वर पर PHP 5.2.9 का उपयोग कर रहा हूं, और ऐसा लगता है कि exec() फ़ंक्शन "गैर-मानक" व्यवहार करता है।exec हमेशा -1 (या 127)

तो मैं चलाने exec("ls", $output, $return_var) तो $output अपेक्षा के अनुरूप वर्तमान फ़ोल्डर में फ़ाइलों की सूची में शामिल होंगे, लेकिन $return_var, -1 के बजाय 0 की स्थापना की जाएगी अपेक्षा के अनुरूप। मैं $return_var का उपयोग कर रहा हूं यह निर्धारित करने के लिए कि आदेश सफलतापूर्वक समाप्त हो गया है, और हर दूसरे सर्वर पर अपेक्षित कार्यों का परीक्षण किया गया है :)

किसी ने कभी इस तरह की स्थिति को मारा?


संपादित करें:

<?php 
$command = "asd"; 

$t1 = time(); 

$output = Array(); 
$result = -5; 
$r = exec($command, $output, $result); 
$t2 = time(); 

echo "<pre>"; 
var_export(Array(
    'command'=>$command, 
    'result'=>$result, 
    'output'=>implode("\n", $output), 
    'r'=>$r, 
    't2-t1'=>$t2-$t1, 
)); 
echo "</pre>"; 

जो भी आदेश मैं $command में डाल दिया, $result हमेशा -1, यहां तक ​​कि अस्तित्वहीन आदेश के लिए हो जाएगा ... यह बहुत ही अजीब है

+2

क्या यदि आपका '$ कमांड' चर एक खाली स्ट्रिंग है ताकि 'exec()' 'ls' को कोई तर्क न दे? क्या बाहर निकलने वाला कोड अभी भी '-1' है? यदि हां, तो क्या आपने अपने मौजूदा सिस्टम के लिए 'ls' के कार्यान्वयन में 'मैन ls' के साथ कार्यान्वित किया है ताकि यह देखने के लिए कि निकास कोड' -1' परिभाषित किया गया है या नहीं? क्या यह अन्य आदेशों के साथ सच है (शायद एक 'du -h index.html')? – sleepynate

+0

ऐसा लगता है कि मैं 'exec (" ") 'को कॉल नहीं कर सकता हूं। यह एक चेतावनी प्रिंट करता है। कोई अन्य आदेश वही व्यवहार करता है। 'नींद 5' रिटर्न -1, 'lsmod' रिटर्न -1 आदि ... – Quamis

+1

केवल एक चीज जो मैं देख सकता हूं वह है [exec php मैन्युअल पृष्ठ पर पोस्ट] (http://www.php.net/manual /en/function.exec.php#76687) लेकिन चूंकि यह अन्य सर्वरों पर काम कर रहा है, यह स्पष्ट नहीं है कि यह क्यों होगा। – Troubadour

उत्तर

1

$ परिणाम == -1 लौटने प्रणाली मान लिया जाये कि यूनिक्स की तरह आधारित (मैं नहीं जानता कि कैसे एक ही कोड के साथ विंडोज कैसा व्यवहार करेंगे)

पीएचपी (5.2.9) कार्यकारी() फ़ंक्शन करता है सी exec() आदिम को कॉल न करें (जो -1 देता है यदि यह प्रक्रिया को प्रतिस्थापित/निष्पादित नहीं कर सका, जो यहां मामला नहीं है)। इसके बजाय यह popen() को कॉल करता है जो एक पाइप बनाता है, एक कांटा() करता है और आपके आदेश के साथ एक खोल निष्पादित करता है। रिटर्न_वल्यू, -1, सी आदिम से प्रत्यक्ष परिणाम नहीं है, बल्कि आपके आदेश को संसाधित करने के तरीके के आधार पर आंतरिक रूप से PHP द्वारा बनाया गया है। दूसरे शब्दों में, "ls" कमांड को अच्छी तरह से निष्पादित किया जा सकता है, जबकि उदाहरण के लिए PHP सही ढंग से पाइप बंद नहीं कर सका।

सी/कोड/मानक/exec.c में सी कोड को देखते हुए, दो कारण हो सकते हैं कि रिटर्न कोड -1 है, एक त्रुटि से ट्रिगर किया गया है; popen के बाद 2 एक होता है() फोन

fp = VCWD_POPEN(cmd_p, "r"); 

    if (!fp) { 
     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to fork [%s]", cmd); 
     goto err; 
    } 
    // ... 
    err: 

    pclose_return = -1; 
    goto done; 

हालांकि इस मामले में, आप नहीं परिणाम देखना होगा, और लॉग एक त्रुटि दिखा सकती है।

बाद में, return_value लाइन

pclose_return = php_stream_close(stream); 

(_php_stream_free को देखते हुए) के माध्यम से सेट किया गया है (php_stream_close() एक मैक्रो _php_stream_free के साथ बदल दिया है()), सबसे अधिक संभावना उम्मीदवार कि लौट सकते हैं -1

है
ret = stream->ops->close(stream, preserve_handle ? 0 : 1 TSRMLS_CC); 

कौन सा बदले में परोक्ष रूप से सी आदिम pclose कॉल()। मैनुअल

pclose() फ़ंक्शन रिटर्न -1 अगर प्रतीक्षा 4 (2) कोई त्रुटि देता है, या कुछ अन्य त्रुटि का पता चला है।

वहाँ पाइप के समापन, कि स्थापित किया जाना परिणामी डेटा नहीं रोकता के दौरान पाया एक त्रुटि होने लगते हैं।तर्कसंगत कारण खोजने के लिए, किसी को ऑपरेटिंग सिस्टम सेटअप और लॉग, PHP कॉन्फ़िगरेशन और संकलन पैरामीटर की जांच करने की आवश्यकता है।

मैं

  • अपने ओएस के लिए पैच लागू करने के लिए, और शायद नवीनतम संस्करण के लिए अद्यतन (यदि लागू हो) की सिफारिश करेंगे,
  • 5.3.3 के लिए पीएचपी अद्यतन करने के लिए (के रूप में नवीनतम अब) के बाद से PHP exec() कोड महत्वपूर्ण रूप से बदल गया।

ध्यान रखें कि संस्करण 5.3 में PHP सुहोसिन मॉड्यूल से संबंधित परिवर्तन थे जो डिफ़ॉल्ट रूप से PHP फ़ाइलों को चलाने पर सुरक्षा को बढ़ाते थे।

+0

हां यह "यूनिक्स-जैसा" था (ईमानदार, ly मुझे कोई विचार नहीं है अगर यह लिनक्स या यूनिक्स स्वाद था)। अच्छा जवाब। समस्या सर्वर व्यवस्थापक द्वारा तय की गई है, लेकिन मुझे नहीं पता कि उसने इसे तोड़ने या ठीक करने के लिए क्या किया ... बात यह थी कि सर्वर को बहुत ही सीमित तरीके से कॉन्फ़िगर किया गया था। मुझे बहुत कम कमांड तक पहुंच थी (उदाहरण के लिए php-cli एसएसएच के माध्यम से उपलब्ध नहीं था, और कई अन्य कमांड। – Quamis

+0

मैं आपके उत्तर को सबसे पूर्ण मानता हूं और मुझे लगता है कि सर्वर व्यवस्थापक ने ओएस को धोया था। – Quamis

0

यह सुनिश्चित करें कि safe mode में नहीं चल रहा है और यह निष्पादन php.ini में disable_functions में सूचीबद्ध नहीं है।

इनमें से किसी भी परिस्थिति में exec() विफल होने का कारण होगा, हालांकि मुझे लगता है कि एक नोटिस उठाया जाएगा।

+0

मैं सुरक्षित मोड में नहीं चल रहा हूं (आप सुरक्षित मोड में exec का उपयोग नहीं कर सकते हैं) और वहां कोई अक्षम फ़ंक्शन नहीं है। – Quamis

+0

@Quamis - मुझे नहीं लगता कि यह आपके मामले में लागू होता है, लेकिन आप सुरक्षित मोड में निष्पादन का उपयोग कर सकते हैं। तब क्या होता है कि सुरक्षित मोड सक्षम होने के साथ, कमांड स्ट्रिंग escapeshellcmd() से बच निकली है। - http://php.net/manual/en/function.exec.php –

0

क्या हम PHP प्रक्रिया को चिपकाने का आउटपुट प्राप्त कर सकते हैं? उसमें वह उत्तर होगा जिसमें हम खोज रहे हैं।

5.2.14 5.2 श्रृंखला में से नवीनतम है। कोई मौका आप इसे आजमा सकते हैं? यदि आप किसी साझा होस्टिंग प्रदाता पर हैं, तो आप यह देखने के लिए स्थानीय रूप से चलाने की संभावना बना सकते हैं कि व्यवहार में बदलाव आया है या नहीं।

0

मैंने इसे दो अलग-अलग लिनक्स पीसी (PHP 5.03 और PHP 5.2.10) पर आज़माया - दोनों ठीक काम करते थे।

पीएचपी 5.2.10 उदाहरण:

array (
    'command' => 'ls', 
    'result' => 0, 
    'output' => 'atmail 
... 
vhosts', 
    'r' => 'vhosts', 
    't2-t1' => 0, 
) 

अपने php.ini फ़ाइल में किसी भी सुरक्षा संबंधी निर्देशों के लिए मैं दो बार जांच करें, निर्देशिका आप खोज करने की कोशिश कर रहे में फाइल अनुमति जाँच चाहते हैं, और देखें कि क्या आपके पास SELinux और/या AppArmor चल रहा है या नहीं।

आप opendir()/readdir() जैसे एक अल्टेरेटिव पर भी विचार कर सकते हैं।

IMHO .. PSM

0

लगता है जैसे समस्या सर्वर व्यवस्थापक द्वारा तय हो गया। मुझे नहीं पता कि उसने क्या किया, लेकिन अब यह काम करता है। बात यह है कि सर्वर व्यवस्थापक सुंदर "सख्त" है और शायद उसे कुछ सिस्टम कॉन्फ़िगरेशन के साथ प्रतिबंधित करने के लिए थोड़ा सा मिला है। उदाहरण के लिए एसएसएच खोल से मैं नहीं देख सका कि PHP द्विआधारी कहाँ स्थापित किए गए थे। मुझे पूरा यकीन है कि एसएसएच खोल को घुमाया गया था, और वेबसर्वर (या तो वह या वे पूरी तरह से अलग सर्वर थे, लेकिन मुझे नहीं पता कि किसी भी तरह के माउंट के बिना यह कैसे संभव था) ...

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