мне нужно немного более гибкое решение, чем 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 - При каких обстоятельствах 'S_IFLNK' и' S_IFSOCK' возвращает истину? – DaveRandom
@DaveRandom: Я никогда не узнавал (или не нуждался в них), я включил их для полноты, когда я получал маски из заголовков C. Они, очевидно, связаны ссылками и сокетами, но когда я экспериментировал, я не мог заставить их запускать. – Leigh
Большое вам спасибо. Это делает именно то, что я хочу! :) – Fania