2012-07-04 142 views
10

我有一個腳本,可以作爲網頁運行,也可以通過控制檯運行。檢測一個PHP腳本是否正在交互運行

檢測使用哪種方法來調用腳本看起來非常簡單,但是當從控制檯運行腳本時,我需要知道腳本是否以交互方式運行(用戶鍵入命令或輸入重定向從一個文件)。

php script.phpphp 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 

我已經不包含的鏈接,插座,或塊設備的例子,但我們沒有理由他們不應該工作,因爲設備模式掩蓋他們在課堂上。

(在Windows未測試 - 里程可能會發生變化)

+1

非常好,+1 - 在什麼情況下會'S_IFLNK'和'S_IFSOCK'返回true? – DaveRandom

+1

@DaveRandom:我從來沒有真正發現過(或者需要它們),當我從C頭文件中獲取掩碼時,我將它們包括在內以獲得完整性。他們顯然是相關的鏈接和套接字,但是當我嘗試時,我無法觸發任何東西。 – 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兼容的操作系統,其中PHP有posix擴展安裝這僅適用。我不知道Windoze等價物。

相關問題