2010-12-07 6 views
6

चलाता है, मैं एक PHP- स्क्रिप्टेड वेब पेज को कोडिंग कर रहा हूं जिसका उद्देश्य किसी जेएफएफएस 2 छवि के फ़ाइल नाम को स्वीकार करना है जिसे पहले सर्वर पर अपलोड किया गया था। स्क्रिप्ट तब छवि के साथ सर्वर पर एक विभाजन को फिर से फ्लैश करना है, और परिणामों को आउटपुट करना है। पुनः आरंभ करने के लिए एक बटन मामले कि अद्यतन सफलतापूर्वक पूरा मेंshell_exec कमांड से आउटपुट प्राप्त करें क्योंकि कमांड

$tmp = shell_exec("update_flash -v " . $filename . " 4 2>&1"); 
echo '<h3>' . $tmp . '</h3>'; 

echo verifyResults($tmp); 

(verifyResults समारोह कुछ HTML है कि क्या अद्यतन आदेश को सफलतापूर्वक पूरा करने के लिए उपयोगकर्ता को इंगित करता है वापस आ जाएगी Ie, प्रदर्शित: मैं इस का उपयोग कर दिया गया था। डिवाइस, इत्यादि)

इस समस्या में यह है कि अद्यतन कमांड को पूरा होने में कई मिनट लगते हैं, और PHP स्क्रिप्ट ब्लॉक तब तक होता है जब तक कि कोई भी आउटपुट लौटने से पहले शेल कमांड पूरा नहीं हो जाता है। इसका आमतौर पर मतलब है कि अद्यतन कमांड चलना जारी रहेगा, जबकि उपयोगकर्ता को HTTP 504 त्रुटि (सबसे खराब) दिखाई देगी या पेज को कई मिनट तक लोड करने की प्रतीक्षा करें।

मैं इस बजाय की तरह कुछ करने के बारे में सोच रहा था:

shell_exec("rm /tmp/output.txt"); 
shell_exec("update_flash -v " . $filename . " 4 2>&1 >> /tmp/output.txt &"); 
echo '<div id="output"></div>'; 
echo '<div id="results"></div>'; 

यह सैद्धांतिक रूप से पृष्ठभूमि में आदेश रखा है और सभी उत्पादन /tmp/output.txt को संलग्न करेंगे।

और फिर, जावास्क्रिप्ट फ़ंक्शन में, मैं समय-समय पर getOutput.php का अनुरोध करता हूं, जो बस /tmp/output.txt की सामग्री मुद्रित करेगा और इसे "आउटपुट" div में चिपकाएगा। एक बार आदेश पूरी तरह से हो जाने के बाद, एक और जावास्क्रिप्ट फ़ंक्शन आउटपुट को संसाधित करेगा और परिणाम "परिणाम" div में प्रदर्शित करेगा।

लेकिन समस्या जो मैं यहां देखता हूं वह यह है कि डिवाइस की फ्लैश मेमोरी को अपडेट करने की प्रक्रिया के दौरान getOutput.php अंततः पहुंच योग्य हो जाएगा, क्योंकि यह विभाजन पर है जिसे अद्यतन के लिए लक्षित किया गया है। तो यह मुझे पहले की तरह उसी स्थिति में छोड़ सकता है, यद्यपि 504 के बिना या एक प्रतीत होता है कि अनंत रूप से लोड होने वाला पृष्ठ।

मैं डिवाइस में getOutput.php को किसी अन्य विभाजन में ले जा सकता हूं, लेकिन फिर मुझे लगता है कि मुझे अभी भी वेबसेवर कॉन्फ़िगरेशन के साथ कुछ फंकी चीजें करना होगा ताकि इसे एक्सेस करने में सक्षम हो सके (वेब्रॉट से इसका एक सिमलिंक होगा , किसी भी अन्य फ़ाइल की तरह, अंततः पुनः फ्लैश के दौरान अधिलेखित किया जाना चाहिए)।

क्या आदेश के आउटपुट को प्रदर्शित करने का कोई अन्य तरीका है, या मुझे अपने समाधान के साथ क्या करना चाहिए?

संपादित करें 1: मैं वर्तमान में कुछ समाधानों का परीक्षण कर रहा हूं। मैं बाद में परिणामों के साथ अपना प्रश्न अपडेट करूंगा।

संपादित करें 2: ऐसा लगता है कि फाइल सिस्टम को अधिलेखित नहीं किया गया है जैसा कि मैंने मूल रूप से सोचा था। इसके बजाए, सिस्टम मौजूदा फाइल सिस्टम को केवल-पढ़ने के मोड में माउंट करने लगता है, इसलिए फाइल सिस्टम को फिर से चमकने के बाद भी मैं getOutput.php तक पहुंच सकता हूं।

मेरे प्रश्न में वर्णित दूसरा समाधान shell_exec के बजाय पॉपन (जैसा कि नीचे दिए गए उत्तर में उल्लिखित) के उपयोग के साथ काम करता है। पृष्ठ लोड होता है, और अजाक्स के माध्यम से मैं output.txt की सामग्री प्रदर्शित कर सकता हूं।

हालांकि, ऐसा लगता है कि output.txt फिर से फ्लैश आदेश असली time-- में यह निष्पादन से अद्यतन आदेश रिटर्न जब तक कुछ भी नहीं प्रदर्शित करने के लिए लगता है से उत्पादन को प्रतिबिंबित नहीं करता। यहां क्या हो रहा है यह देखने के लिए मुझे और परीक्षण करने की आवश्यकता होगी।

संपादित करें 3: के रूप में मैं इसे का उपयोग कोई बात नहीं, यह फ़ाइल की तरह लग रहा वर्तमान है। मैं बस देरी कर रहा था, जबकि कर्नेल ने कुछ जेएफएफएस 2-संबंधित कार्यों को विभाजन के उपयोग से ट्रिगर किया था जिस पर स्रोत जेएफएफएस 2 छवि संग्रहित की गई थी। मुझे नहीं पता क्यों, लेकिन यह स्पष्ट रूप से सभी PHP स्क्रिप्ट को तब तक अवरुद्ध कर देता है जब तक यह पूरा नहीं हो जाता है।

इसके आसपास काम करने के लिए, मैं एक अलग स्क्रिप्ट में अद्यतन कमांड आमंत्रण डालने जा रहा हूं और इसे अजाक्स के माध्यम से अनुरोध करता हूं - इस तरह, उपयोगकर्ता को सिस्टम पर अभी भी इंतजार करते समय कम से कम प्रीपेक्टेड प्रतिक्रिया प्राप्त होगी। popen पर

उत्तर

3
+0

पॉपन PHP को वांछित रूप से अवरुद्ध करने से रोकने के लिए प्रतीत होता है, लेकिन किसी भी तरह मेरा आदेश तुरंत मेरी आउटपुट फ़ाइल को अपडेट नहीं कर रहा है - विवरण के लिए मेरे प्रश्न का संपादन 2 देखें। –

+0

कोई बात नहीं, पॉपन अपेक्षित के रूप में काम कर रहा था। –

1

दिलचस्प परिदृश्य।

मेरा पहला विचार proc_ * और $ _SESSION के संबंध में कुछ करना था, लेकिन मुझे यकीन नहीं है कि यह काम करेगा या नहीं। इसे आज़माएं, लेकिन यदि नहीं ...

यदि आप प्रक्रिया के दौरान फ़ाइल को फिसलने के बारे में चिंतित हैं, तो आप हमेशा माध्यमिक प्रक्रिया में एक MySQL डेटाबेस को तुरंत चालू कर सकते हैं और उसे लिख सकते हैं। डेटाबेस किसी अन्य विभाजन पर मौजूद हो सकता है, और आप इसे स्थानीय आईपी द्वारा संबोधित कर सकते हैं और सिस्टम रूटिंग का ख्याल रखेगा।

$_SESSION = array(
    1 => array("pipe", "w"), 
); 

हालांकि मैं एक तरह से संदेह नहीं है कि काम करेंगे:

संपादित

मैं सत्र के साथ proc_ * उल्लेख किया है, मैं this को कुछ इसी तरह जहां $ descriptorspec बन जाएगा मतलब है। प्रक्रिया स्मृति में $ _SESSION को लिखने को समाप्त कर देगी जो पहली स्क्रिप्ट मारे जाने के बाद मौजूद नहीं है।

संपादित 2

वास्तव में, कि नोट पर, आप memcache इंस्टॉल करें और अपने माध्यमिक प्रक्रिया स्मृति है, जो तब हो अपने वेब interfaced प्रक्रिया द्वारा फिर से पढ़ सकते हैं पर लिखते हो सकता था।

+0

यह एक हल्के एम्बेडेड लिनक्स सिस्टम है, इसलिए मुझे नहीं लगता कि मैं एक MySQL कार्यान्वयन के लिए स्टोरेज स्पेस का भुगतान कर सकता हूं, भले ही मेरे पास बाइनरी हो :( –

1

यदि आप डॉक्रूट को मिटाते हैं तो कोई संसाधन/स्क्रिप्ट नहीं है जो इस समय के दौरान उपयोगकर्ता से अनुरोधों का जवाब दे सकती है। इसलिए आपको उसी अनुरोध में उपयोगकर्ता को अपडेट भेजना होगा जो मिटा देता है। इसके लिए आपको खोल प्रक्रिया शुरू करने की आवश्यकता है और तुरंत PHP पर वापस आना आवश्यक है। इसे pcntl_fork() और pcntl_exec() के साथ पूरा किया जा सकता है। आपकी PHP स्क्रिप्ट को अब क्लाइंट को खोल स्क्रिप्ट का आउटपुट भेजना चाहिए। यदि शेल स्क्रिप्ट/tmp में फ़ाइल में संलग्न होती है, तो आप fpassthru() फ़ाइल कर सकते हैं और खोल स्क्रिप्ट समाप्त होने तक इसे साफ़ कर सकते हैं।

1

के बारे में अपने हालांकि:

मेरा अनुमान है कि आप एक धारा के रूप में फ़ाइल का उपयोग करने की कोशिश कर रहे है। मैंने कोई उत्पादन परीक्षण नहीं किया है, लेकिन मेरा मानना ​​है कि फ़ाइल केवल fclose() पर डिस्क पर लिखी जाएगी।

यदि आप लगातार स्क्रिप्ट # 2 में फ़ाइल में लिख रहे हैं, तो वे लिखते हैं कि वास्तव में फ़ाइल बंद होने तक स्मृति में सीधे जा रहे हैं।

फिर से - मैं इसे सत्यापित नहीं कर सकता, लेकिन यदि आप इसका परीक्षण करना चाहते हैं, तो प्रत्येक लेखन के लिए फ़ाइल को फिर से खोलने और बंद करने का प्रयास करें।यह मेरे सिद्धांत की पुष्टि या इनकार करेगा और आप तदनुसार अपने दृष्टिकोण को संशोधित कर सकते हैं।

+0

दूसरी स्क्रिप्ट बस फ़ाइल को पढ़ती है और इसकी सामग्री को आउटपुट करती है; मैं नहीं हूं कोई भी लिखना। फ़ाइल स्क्रिप्ट # 1 में शुरू हुई कमांड द्वारा लिखी गई है: ("update_flash -v"। $ filename। "4 2> और 1 >> /tmp/output.txt और") –

+1

ओह हाँ - क्षमा करें मेरे पास यह था कि आप किसी कारण से दो PHP स्क्रिप्ट का उपयोग कर रहे थे। क्या यह संभव है कि फाइल लॉक के साथ कुछ संघर्ष हो? – Craige

+0

एचएम, वास्तव में यह मामला हो सकता है। मैंने बिल्ली का उपयोग करके जांच की, जो शायद PHP के फॉपेन के समान व्यवहार करें। –