2012-07-04 17 views
10

मेरे पास एक स्क्रिप्ट है जिसे वेब पेज के रूप में और कंसोल के माध्यम से चलाने के लिए डिज़ाइन किया गया है।पता लगाएं कि कोई PHP स्क्रिप्ट इंटरैक्टिव रूप से चल रहा है या नहीं

स्क्रिप्ट को आमंत्रित करने के लिए किस विधि का उपयोग किया गया था, यह पता लगाना कि सीधे सीधा आगे बढ़ रहा है, लेकिन जब कंसोल से स्क्रिप्ट चलाया जा रहा है, तो मुझे यह जानना होगा कि स्क्रिप्ट को अंतःक्रियात्मक रूप से चलाया जा रहा है या नहीं (उपयोगकर्ता टाइपिंग कमांड, या इनपुट रीडायरेक्ट किया गया है एक फाइल से)।

php script.php बनाम php script.php < input_file

यह संभव है?

उत्तर

25

मैं भी posix_isatty की तुलना में ज्यादा लचीला समाधान है कि पता लगा सकता है की जरूरत:

  • स्क्रिप्ट टर्मिनल
  • से चलाया जा रहा है एक पाइप के माध्यम से या एक फ़ाइल से डेटा प्राप्त स्क्रिप्ट है
  • क्या आउटपुट को

कुछ प्रयोग करने और libc हेडर के माध्यम से खोदने के बाद, मैं एक बहुत ही सरल वर्ग के साथ आया जो कर सकता है उपरोक्त सभी और अधिक।

class IOMode 
{ 
    public $stdin; 
    public $stdout; 
    public $stderr; 

    private function getMode(&$dev, $fp) 
    { 
     $stat = fstat($fp); 
     $mode = $stat['mode'] & 0170000; // S_IFMT 

     $dev = new StdClass; 

     $dev->isFifo = $mode == 0010000; // S_IFIFO 
     $dev->isChr = $mode == 0020000; // S_IFCHR 
     $dev->isDir = $mode == 0040000; // S_IFDIR 
     $dev->isBlk = $mode == 0060000; // S_IFBLK 
     $dev->isReg = $mode == 0100000; // S_IFREG 
     $dev->isLnk = $mode == 0120000; // S_IFLNK 
     $dev->isSock = $mode == 0140000; // S_IFSOCK 
    } 

    public function __construct() 
    { 
     $this->getMode($this->stdin, STDIN); 
     $this->getMode($this->stdout, STDOUT); 
     $this->getMode($this->stderr, STDERR); 
    } 
} 

$io = new IOMode; 

कुछ उदाहरण उपयोग, यह दिखाने के लिए कि यह क्या पता लगा सकता है।

इनपुट:

$ php io.php 
// Character device as input 
// $io->stdin->isChr == true 

$ echo | php io.php 
// Input piped from another command 
// $io->stdin->isFifo == true 

$ php io.php < infile 
// Input from a regular file (name taken verbatim from C headers) 
// $io->stdin->isReg == true 

$ mkdir test 
$ php io.php < test 
// Directory used as input 
// $io->stdin->isDir == true 

आउटपुट:

$ php io.php 
// $io->stdout->isChr == true 

$ php io.php | cat 
// $io->stdout->isFifo == true 

$ php io.php > outfile 
// $io->stdout->isReg == true 

त्रुटि:

$ php io.php 
// $io->stderr->isChr == true 

$ php io.php 2>&1 | cat 
// stderr redirected to stdout AND piped to another command 
// $io->stderr->isFifo == true 

$ php io.php 2>error 
// $io->stderr->isReg == true 

मैं लिंक, सॉकेट, या ब्लॉक उपकरणों के लिए उदाहरण शामिल नहीं है, लेकिन वहाँ कोई कारण नहीं है उन्हें काम नहीं करना चाहिए, क्योंकि उनके लिए डिवाइस मोड मास्क कक्षा में हैं।

(विंडोज पर परीक्षण नहीं - लाभ भिन्न हो सकते हैं)

+1

बहुत अच्छा, +1 - के तहत किन परिस्थितियों 'S_IFLNK' और' सच लौट S_IFSOCK' होगा? – DaveRandom

+1

@ डेव रैंडम: मैंने वास्तव में कभी नहीं पाया (या उनकी आवश्यकता है), जब मैं सी हेडर से मास्क प्राप्त कर रहा था, तो मैंने उन्हें पूर्णता के लिए शामिल किया। वे स्पष्ट रूप से संबंधित लिंक और सॉकेट से संबंधित हैं, लेकिन जब मैं प्रयोग कर रहा था तो मुझे उन्हें ट्रिगर करने के लिए कुछ भी नहीं मिला। – Leigh

+0

आपको बहुत बहुत धन्यवाद। यह वही करता है जो मैं चाहता हूं! :) – Fania

4

posix_isatty()

if (posix_isatty(0)) { 
    // STDIN is a TTY 
} else { 
    // STDIN is a pipe or has no associated TTY 
} 

जाहिर POSIX शिकायत ऑपरेटिंग सिस्टम, जहां पीएचपी posix एक्सटेंशन इंस्टॉल है पर यह केवल काम करता है। मुझे विंडोज समकक्ष के बारे में पता नहीं है।

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