2012-08-30 11 views
11

निष्पादन आदेश मेरे सर्वर पर काम नहीं करता है, यह कुछ भी नहीं करता है, मैंने सुरक्षित_मोड बंद कर दिया है, और सत्यापित किया है कि सभी कंसोल कमांड काम कर रहे हैं, मैंने पूर्ण पथों के साथ प्रयास किया है। मैंने अनुप्रयोगों पर अनुमतियों की जांच की है और मेरे पास आवश्यक सभी एप्लिकेशन निष्पादन अनुमतियां हैं। मुझे नहीं पता कि और क्या करना है, यहां दिए गए कोडों की रैंड डाउन हैं।मैं exec() समस्याओं को कैसे डीबग कर सकता हूं?

echo exec('/usr/bin/whoami'); 

echo exec('whoami'); 

exec('whoami 2>&1',$output,$return_val); 
if($return_val !== 0) { 
    echo 'Error<br>'; 
    print_r($output); 
} 

exec('/usr/bin/whoami 2>&1',$output,$return_val); 
if($return_val !== 0) { 
    echo 'Error<br>'; 
    print_r($output); 
} 

पिछले दो कोड प्रदर्शन:

Error 
Array () 

मैं सर्वर सेवा से संपर्क किया है और उन्होंने मुझे मदद नहीं कर सकता, वे क्यों कार्यकारी आदेश काम नहीं कर रहा पता नहीं है। मेरी खराब अंग्रेजी क्षमा करें।

+0

"काम नहीं कर रहे" से आपका क्या मतलब है? कोई त्रुटि आउटपुट? – Touki

+0

क्या आपने error.log की कोशिश की? – Rolice

+0

त्रुटि सेटिंग्स 'display_errors = 1' और 'error_report = E_ALL'? (ध्यान दें, आपको लाइव सिस्टम पर त्रुटियों को प्रदर्शित नहीं करना चाहिए। अगर आप कर चुके हैं, इसे अक्षम करें) – KingCrunch

उत्तर

10

वहाँ के तहत, /etc/php.ini पर एक नजर है:

; This directive allows you to disable certain functions for security reasons. 
; It receives a comma-delimited list of function names. This directive is 
; *NOT* affected by whether Safe Mode is turned On or Off. 
; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.disable-functions 
disable_functions = 

सुनिश्चित करें कि कार्यकारी इस तरह सूचीबद्ध नहीं है, बनाने:

disable_functions=exec 

यदि ऐसा है, तो इसे हटाएं और अपाचे को पुनरारंभ करें।

आसान डिबगिंग के लिए मैं आमतौर पर php फ़ाइल को मैन्युअल रूप से निष्पादित करना चाहता हूं (मुख्य आईएनआई में इसे सेट किए बिना अधिक त्रुटियों का अनुरोध कर सकता हूं)। तो हैडर जोड़ सकता हूँ करने के लिए: फ़ाइल की शुरुआत करने के लिए

#!/usr/bin/php 
ini_set("display_errors", 1); 
ini_set("track_errors", 1); 
ini_set("html_errors", 1); 
error_reporting(E_ALL); 

, यह chmod +x myscript.php का उपयोग कर नियंत्रण दिया जाएगा और यह ./myscript.php निष्पादित। यह विशेष रूप से व्यस्त सर्वर पर बहुत ही सावधान है जो लॉग फ़ाइल में बहुत कुछ लिखता है।

संपादित

एक अनुमतियाँ मुद्दे की तरह लगता है। एक बैश स्क्रिप्ट बनाएं जो echo "helo world" के रूप में कुछ आसान करे और इसे चलाने का प्रयास करें। सुनिश्चित करें कि आपके पास फ़ाइल फ़ाइल और फ़ाइल वाले फ़ोल्डर के लिए अनुमतियां हैं। आप सिर्फ परीक्षण के लिए chmod 755 कर सकते हैं।

+0

'disabled_functions' मेरे' php.ini' में खाली है, जैसा कि आपने सुझाव दिया है, मैं स्क्रिप्ट चलाता हूं और कंसोल कुछ भी नहीं दिखाता है। – carcargi

+0

@Necroside उत्तर अपडेट किया गया। – Kuf

+0

धन्यवाद, यह चाल है, समस्या यह थी कि किसी भी तरह (जैसा कि मेरे क्लाइंट के पास सर्वर तक पहुंच है और वह सोचता है कि वह एक विशेषज्ञ एक्सडी है), उसने ऐप्स की अनुमतियों की प्रतिलिपि बनाई और बदल दी। मैंने उन्हें मूल फ़ोल्डर में वापस ले जाया है और फिर पथ को कॉन्फ़िगर किया है, अब सब कुछ काम करता है, मुझे एप्लिकेशन की अनुमतियों का परीक्षण करते समय यह मिला। धन्यवाद। – carcargi

4

आप आउटपुट नहीं निकाला और वापसी exec आदेशों की कोड, thoses पराक्रम जानकारियां कि समस्या की व्याख्या हैं कर सकते हैं ...

exec('my command', $output, $return); 
+0

बस प्रश्न में कोड जोड़ा और इस जवाब को नहीं देखा, यह सिर्फ यह दिखाता है। 'त्रुटि ऐरे()' – carcargi

+0

और $ return_val चर क्या है? – YohannP

5

चूंकि आप देशी संदर्भ में PHP संदर्भ से बाहर निकल रहे हैं, तो आपको कई समस्याएं डीबगिंग करने जा रही हैं।

सबसे पहले और सबसे मूर्खतापूर्ण मैंने अतीत में उपयोग किया है, स्क्रिप्ट के आउटपुट को लॉग फ़ाइल में लिख रहा है और PHP निष्पादन के दौरान इसे तैयार कर रहा है।

<?php 
shell_exec("filename > ~/debug.log 2>&1"); 

तो एक अलग खोल में:

tail -200f ~/debug.log 

जब आप अपने PHP स्क्रिप्ट निष्पादित, अपने खोल कॉल द्वारा अपना त्रुटियों और उत्पादन अपने debug.log फ़ाइल में प्रदर्शित करेगा।

0

कुछ और नोट्स।

  • डिबगिंग के लिए हमेशा var_dump() में अपने कार्यकारी/shell_exec समारोह लपेटो।

  • error_reporting(-1);, पर होना चाहिए के रूप में भी set_error_handler("var_dump");display_errors होना चाहिए, अंतिम उपाय के रूप - अगर पीएचपी ही execvp वरना आह्वान नहीं किया है, तो केवल देखने के लिए।

  • 2>&1 का उपयोग करें (एसटीडीईआरआर को एसटीडीओआरटी स्ट्रीम में विलय करें) यह देखने के लिए कि कोई आमंत्रण विफल क्यों होता है।
    कुछ मामलों आप एक अतिरिक्त खोल मंगलाचरण में अपने आदेश रैप करने के लिए आवश्यकता हो सकती है के लिए:

    // capture STDERR stream via standard shell 
    shell_exec("/bin/sh -c 'ffmpeg -opts 2>&1' "); 
    

    वरना लॉग फ़ाइल अनुप्रेषित रूप @Mike ने सलाह दी सबसे recommendable दृष्टिकोण है।

  • त्रुटि संदेशों को अन्यथा उजागर करने के लिए विभिन्न निष्पादन कार्यों के बीच वैकल्पिक। जबकि वे ज्यादातर एक ही बात करते हैं, उत्पादन वापसी रास्तों से बदलते हैं:

    1. exec() या तो → समारोह परिणाम के रूप में उत्पादन देता है, या वैकल्पिक $output परमाटर के माध्यम से।
      भी $return_var पैरामीटर प्रदान करता है, जिसमें रन एप्लिकेशन या खोल का इरनो/एक्ज़िट कोड होता है। आप प्राप्त कर सकते हैं:

      • ENOENT (2) - ऐसा कोई फ़ाइल
      • EIO (127) - आईओ त्रुटि:
    2. shell_exec() फ़ाइल नहीं मिली → क्या आप खोल के लिए ज्यादातर चलाना चाहते है स्टाइल अभिव्यक्तियां
      वापसी मूल्य को असाइन/प्रिंट करना सुनिश्चित करें उदा। var_dump(shell_exec("..."));

    3. `` इनलाइन बैकटिक → shell_exec के समान हैं।

    4. system()exec के समान है, लेकिन हमेशा आउटपुट को फ़ंक्शन परिणाम के रूप में लौटाता है (इसे प्रिंट करें!)। इसके अतिरिक्त परिणाम कोड कैप्चर करने की अनुमति देता है।

    5. passthru() → एक और exec वैकल्पिक है, लेकिन हमेशा किसी भी STDOUT परिणाम PHPs आउटपुट बफर को भेजता है। जो कई बार इसे सबसे उपयुक्त निष्पादन रैपर बनाता है।

    6. popen() या बेहतर proc_open() → व्यक्तिगत रूप से STDOUT और STDERR को कैप्चर करने की अनुमति देता है।

  • अधिकांश खोल त्रुटियों PHPs या अपाचे error.log में हवा जब पुन: निर्देशित नहीं। यदि कोई उपयोगी त्रुटि संदेश उत्पन्न नहीं करता है तो अपने syslog या अपाचे लॉग की जांच करें।

सबसे सामान्य समस्याओं PHP/दीप नए चेहरे के नाक में दम कर रहे हैं:

  • रूप @Kuf ने उल्लेख किया: पुराना वेब होस्टिंग की योजना के लिए, आप अभी भी मिल सकता है safe_mode या disable_functions सक्षम होना चाहिए। PHP निष्पादन कार्यों में से कोई भी काम नहीं करेगा। (सर्वश्रेष्ठ, एक बेहतर प्रदाता खोजने के लिए कुछ "सीजीआई" की जांच -। लेकिन अपने स्वयं के पीएचपी दुभाषिया स्थापित नहीं है जबकि अकुशल)

  • इसी तरह निकल रहा/SELinux/Firejail कभी कभी जगह में हो सकता है। वे प्रत्येक प्रक्रिया को नई प्रक्रियाओं को बढ़ाने की क्षमता को सीमित करते हैं।

  • इरादा बाइनरी मौजूद नहीं है। बहुत अधिक वेबहोस्ट में ffmpeg प्रीइंस्टॉल किए गए टूल हैं। आप तैयारी के बिना मनमाने ढंग से खोल कमांड नहीं चला सकते हैं। कुछ चीजों को स्थापित करने की आवश्यकता है!

    // Check if `ffmpeg` is actually there: 
    var_dump(shell_exec("which ffmpeg")); 
    
  • PATH बंद है। यदि आपने कस्टम टूल इंस्टॉल किए हैं, तो आपको यह सुनिश्चित करना होगा कि वे पहुंच योग्य हैं। var_dump(shell_exec("ffmpeg -opts")) का उपयोग सभी सामान्य पथों की खोज करेगा - या अपाचे को बताया गया है/बाधित किया गया है (अक्सर केवल /bin:/usr/bin)।

    print_r($_SERVER); के साथ जांचें कि आपके पैथ में क्या है और यदि वह उपकरण शामिल है जिसे आप चलाने के लिए चाहते हैं।

    // run with absolute paths to binary 
    var_dump(shell_exec("/bin/sh -c '/usr/local/bin/ffmpeg -opts 2>&1'")); 
    

    यह कुछ हद तक खोल अवधारणा को नष्ट कर रहा है: और आप सर्वर सेटिंग्स अनुकूलित करने के लिए (/ etc/apache2/envvars), या पूर्ण पथ का उपयोग पड़ सकता है। व्यक्तिगत रूप से मुझे यह पसंद नहीं लगता है। हालांकि सुरक्षा उद्देश्यों के लिए यह समझ में आता है; पाठ्यक्रम की एक कस्टम स्थापना का उपयोग करने के लिए इसके अलावा।

  • अनुमतियां

    1. आदेश बीएसडी/Linux सिस्टम पर एक बाइनरी चलाने के लिए, यह की जरूरत है "निष्पादन" किए जाने के लिए। यह chmod a+x ffmpeg करता है।

    2. अपाचे उपयोगकर्ता द्वारा आपकी कस्टम स्क्रिप्ट को चलाने के लिए आगे बढ़ने की आवश्यकता है, जो आपकी PHP स्क्रिप्ट चलती हैं।

    3. अधिक समकालीन सेटअप PHP का निर्माण एफपीएम मोड (सुएक्सैक + फास्टसीजीआई) का उपयोग करते हैं, जहां आपका वेबहोस्टिंग खाता PHP के साथ चलता है।

  • SSH के साथ टेस्ट। इसे बिना कहने के जाना चाहिए, लेकिन PHP के माध्यम से कमांड चलाने से पहले, इसे वास्तविक खोल में परीक्षण करना बेहद समझदार होगा। उदाहरण के साथ जांच ldd ffmpeg यदि सभी lib निर्भरताएं हैं, और यदि यह अन्यथा काम करती है।

  • इनपुट मूल्यों (प्राप्त, पोस्ट, फ़ाइल नाम, उपयोगकर्ता डेटा) कि कार्यकारी तार में आदेश तर्क के रूप में पारित करने के escapeshellarg() के साथ भाग जाने की जरूरत है।

    $q = "escapeshellarg"; 
    var_dump(shell_exec("echo {$q($_GET['text'])} | wc")); 
    

    नहीं तो आप खोल वाक्यविन्यास त्रुटियों को आसानी से मिल जाएगा; और शायद बाद में स्थापित कोड का फायदा उठाएं ...

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