Выполнить «меньше» из командной строки PHP w / Scrolling

Я хочу выполнить less и подобных программ из командной строки в PHP.

Я пробовал обычных подозреваемых (exec, shell_exec, passthru и т. Д.), И хотя многие из них могут выгружать файл на экран, этот процесс заканчивается, прежде чем я смогу его использовать. Если бы я хотел cat , я бы использовал его.

Как я могу выполнить программу таким образом?

Вы можете использовать proc_open для подачи ввода и получения вывода из процесса через каналы. Тем не менее, это не похоже на то, что он позволяет взаимодействовать с пользователем через каналы, поскольку он в основном ухудшает команду cat . Вот мой первый (неудачный) подход:

 <?php $dspec = array( 0 = array('pipe', 'r'), // pipe to child process's stdin 1 = array('pipe', 'w'), // pipe from child process's stdout 2 = array('file', 'error_log', 'a'), // stderr dumped to file ); // run the external command $proc = proc_open('less name_of_file_here', $dspec, $pipes, null, null); if (is_resource($proc)) { while (($cmd = readline('')) != 'q') { // if the external command expects input, it will get it from us here fwrite($pipes[0], $cmd); fflush($pipes[0]); // we can get the response from the external command here echo fread($pipes[1], 1024); } fclose($pipes[0]); fclose($pipes[1]); echo proc_close($proc); 

Я думаю, что для некоторых команд этот подход может действительно работать – и есть некоторые примеры в man- proc_open php для proc_open которые могут быть полезны для просмотра – но для less , вы получаете весь файл обратно и не имеете возможности для взаимодействия, возможно, по причинам, упомянутым ответом Viper_Sb.

… Но кажется, что достаточно легко имитировать less если это все, что вам нужно. Например, вы можете прочитать вывод команды в массив строк и передать ее в куски размером с укусом:

 <?php $pid = popen('cat name_of_file_here', 'r'); $buf = array(); while ($s = fgets($pid, 1024)) $buf[] = $s; pclose($pid); for ($i = 0; $i < count($buf)/25 && readline('more') != 'q'; $i++) { for ($j = 0; $j < 25; $j++) { echo array_shift($buf); } } 

Я не считаю, что это возможно. PHP не является средой VM / shell, команды, к которой он должен обращаться, к другим программам, все возвращают к нему контроль, и обычно нет взаимодействия во время работы PHP.

Последнее, попробуйте с операторами backtick, если это не сработает, то я уверен, что вы не можете этого сделать, не записывая что-то самостоятельно, что будет спать и разрешить ввод пользователя и т. Д. … по умолчанию нет

 `nano file.txt` 

Добавление exec ('stty cbreak'); к скрипту PHP также устраняет проблему.

Я помещаю следующее в файл, определенный параметром auto_prepend_file в php.ini

Итак, я бы сделал что-то вроде редактирования php.ini следующим образом:

 auto_prepend_file = /path/to/prepend.php 

Затем в, /path/to/prepend.php, я бы добавил следующую строку:

 if (php_sapi_name() == 'cli') exec('stty cbreak'); 

Я не совсем уверен в этом. Я читал отчеты об ошибках для PHP. Однако я не уверен в версиях. Я заметил проблему со следующей настройкой:

 $ php -v PHP 5.3.3 (cli) (built: Jul 12 2013 20:35:47) Copyright (c) 1997-2010 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies 

Однако следующее не показало проблемы:

 # php -v PHP 5.3.26 (cli) (built: Oct 21 2013 16:50:03) Copyright (c) 1997-2013 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2013 Zend Technologies with the ionCube PHP Loader v4.4.1, Copyright (c) 2002-2013, by ionCube Ltd. 

Стоит отметить, что версия без этой проблемы использует cPanel, а другая использует установку CentOS 6 по умолчанию через yum.