CLI

2012-02-20 17 views
14

वैसे भी PHP में STDIN पर गैर-ब्लॉक कर रहा है वहाँ पीएचपी साथ STDIN से पढ़ने के लिए है कि गैर अवरुद्ध:CLI

stream_set_blocking(STDIN, false); 
echo fread(STDIN, 1); 

और इस:

$stdin = fopen('php://stdin', 'r'); 
stream_set_blocking($stdin, false); 
echo 'Press enter to force run command...' . PHP_EOL; 
echo fread($stdin, 1); 

मैं इस कोशिश की लेकिन यह अभी भी fread तक कुछ डेटा प्राप्त करता है तब तक ब्लॉक करता है।

मैंने इस (7 वर्ष की उम्र) के बारे में कुछ खुली बग रिपोर्ट देखी, इसलिए यदि यह नहीं किया जा सकता है, तो क्या कोई भी ऐसे क्रूड हैक्स को जानता है जो इसे पूरा कर सकता है (विंडोज और लिनक्स पर)?

+3

सुनिश्चित नहीं है कि मैं समझता हूं कि गैर-अवरोधक व्यवहार क्या होना चाहिए। अगर स्टडीन को खिलाया जाने का इंतजार करने के लिए कुछ भी नहीं है, तो 'गलत() 'एक झूठी वापसी करनी चाहिए? ईओएफ से यह कैसे अंतर करेगा? मुझे लगता है कि यह निर्धारित करने के लिए कि क्या कोई वर्णनात्मक विफलता नहीं है, यह निर्धारित करने के लिए कि आपको stdin पर डेटा देखने का निर्धारण करने के लिए 'fread()' से कुछ प्रकार की टेस्ट * अन्य * की आवश्यकता है। – Graham

+0

@ ग्राहम 'फ्रेड' वापस नहीं आएगा, यानी स्क्रिप्ट के निष्पादन को रोकें, जब तक कि इनपुट 'STDIN' को नहीं दिया जाता है। मूल रूप से जो मैं चाहता हूं, यह जांचना है कि 'STDIN' में कोई उपयोगकर्ता इनपुट है या नहीं, और यदि नहीं, जारी रखें, या फिर कुछ अन्य सामान चलाएं। – Petah

+0

@ ग्राहम "गैर अवरोधन" का अर्थ है कि 'फ्रेड()' तुरंत वापस आना चाहिए, भले ही वह डेटा की मात्रा को पढ़ न सके, इसे पढ़ना चाहिए (दूसरा तर्क), लेकिन इससे कम। इस मामले में इसे एक खाली स्ट्रिंग वापस करनी चाहिए। @Petah क्या आपने 'fopen ('php: // stdin)' कोशिश की? मुझे अस्पष्टता से याद है, कि मुझे पहले 'एसटीडीआईएन' के साथ समस्याएं थीं। – KingCrunch

उत्तर

12

यहां मैं क्या कर सकता हूं। यह लिनक्स में ठीक काम करता है, लेकिन विंडोज़ पर, जैसे ही मैंने एक कुंजी मारा, इनपुट दबाए जाने तक इनपुट बफर किया जाता है। मैं वर्तमान में स्ट्रीम पर बफरिंग को अक्षम करने का तरीका ढूंढ रहा हूं, या विशेष रूप से PHP में STDIN पर।

<?php 

function non_block_read($fd, &$data) { 
    $read = array($fd); 
    $write = array(); 
    $except = array(); 
    $result = stream_select($read, $write, $except, 0); 
    if($result === false) throw new Exception('stream_select failed'); 
    if($result === 0) return false; 
    $data = stream_get_line($fd, 1); 
    return true; 
} 

while(1) { 
    $x = ""; 
    if(non_block_read(STDIN, $x)) { 
     echo "Input: " . $x . "\n"; 
     // handle your input here 
    } else { 
     echo "."; 
     // perform your processing here 
    } 
} 

?> 
+0

धन्यवाद, यह मेरे मामले के लिए काम करेगा। लेकिन अगर आप इसे (प्रवेश कुंजी चीज) के साथ संगत कर सकते हैं तो बेहतर भी। यदि कोई बेहतर उत्तर नहीं है तो मैं आपको बक्षीस देता हूं। – Petah

+0

मैंने इसे अपनी स्क्रिप्ट के साथ एकीकृत किया है, यह तथ्य अच्छी तरह से काम करता है कि इसे प्रवेश के लिए इंतजार करना है। हर बार जब मैं विंडो में Alt + टैब करता हूं, तो यह रुक जाता है और प्रवेश के लिए प्रतीक्षा करता है। – Petah

+0

बस इस प्रश्न पर stubmle'd और अगर आप stream_set_read_buffer (STDIN, 0) का उपयोग कर रहे हैं तो यह काम कर सकता है; और, जैसा कि आपने पहले ही उल्लेख किया है, stream_set_blocking (STDIN, false); - पहले व्यक्ति को पढ़ने पर unbuffered होने के लिए stdin सेट करना चाहिए, दूसरा सेट यह गैर अवरोधक होने के लिए है जो unbuffered से थोड़ा अलग है। –

1

Petah, मैं सीधे इस का पीएचपी पक्ष के साथ मदद नहीं कर सकता, लेकिन मैं एक लेख मैंने कुछ समय पहले भर में भाग गया के लिए आप उल्लेख कर सकते हैं जिसमें किसी ने नामित पाइप के लंबित डेटा के अस्तित्व के लिए शेल स्क्रिप्ट के भीतर परीक्षण करके ट्रांजिस्टर को अनुकरण किया। यह एक आकर्षक पठन है, और पूरी तरह से geekiness के नए स्तर पर खोल स्क्रिप्टिंग लेता है। :-)

लेख यहाँ है: अपने "कच्चे हैक्स" अनुरोध के जवाब में http://www.linusakesson.net/programming/pipelogic/

तो ..., मैं तुम्हें नामित पाइप के माध्यम से अपने stdio अलग धकेलना सकता है लगता है, तो exec() उपकरण जिसका स्रोत शामिल किया गया है यह जांचने के लिए ऊपर दिए गए यूआरएल पर कि कुछ भी पाइप के माध्यम से भेजा जा रहा है या नहीं। आप शायद सामान के साथ मदद करने के लिए कुछ रैपर कार्यों को विकसित करना चाहते हैं।

मुझे संदेह है कि पाइपलोगिक समाधान केवल लिनक्स-केवल है, या कम से कम एक यूनिक्स जैसी ऑपरेटिंग सिस्टम की आवश्यकता होगी। कोई विचार नहीं कि यह विंडोज पर कैसे पूरा किया जा सकता है।

+1

क्षमा करें, मैं वास्तव में नहीं देखता कि यह मेरी समस्या से कैसे मदद करता है। – Petah

+0

@Petah - एक पाइप से पढ़ने वाले एक गैर-अवरुद्ध फ़्रेड() को एक फ़ंक्शन द्वारा डुप्लिकेट किया जा सकता है जो जांचने के बाद केवल एक अवरुद्ध फ़्रेड() चलाएगा कि कोई पाइप पर कोई डेटा प्रतीक्षा कर रहा है या नहीं। मेरे द्वारा पोस्ट किए गए लिंक पर टूल आपको उस स्थिति का परीक्षण करने देता है। मुझे पूरा यकीन है कि यह दृष्टिकोण विंडोज़ में नामित पाइप की कमी के कारण काम नहीं करेगा, इसलिए मैं इसे और काम नहीं करूंगा, क्योंकि विंडोज संगतता आपके प्रश्न की स्थिति है। – ghoti

+0

वैसे भी धन्यवाद :) – Petah

0

बस एक नोटिस, जो अब एसटीडीआईएन कार्य को अवरुद्ध नहीं कर रहा है।

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