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

StackOverflow https://stackoverflow.com/questions/3479559

  •  28-09-2019
  •  | 
  •  

Вопрос

Я хочу выполнить 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);

Я думаю, что для некоторых команд этот подход может на самом деле работать - и есть несколько примеров в PHP Manpage для 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 Creak'); к сценарию 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top