Как я могу передать grep через tac для возврата значения, не убивая процесс в функции php exec()?

Я пытаюсь найти самый последний доступ к «foo» в nginx access.log, и когда я запускаю следующую команду через командную строку, она работает точно так, как ожидалось, и очень быстро.

$output = exec('tac /var/log/nginx/access.log | grep -m1 "foo"');
echo $output;

Однако, запуская его через функцию exec() php, время ожидания истекает через 30 секунд. Если я убью процесс tac на сервере, PHP выдаст ожидаемый результат, как только процесс будет остановлен. я пытался

grep "foo" /var/log/nginx/access.log | tail -1

но для поиска результата требуется целых 22 секунды вместо доли секунды в командной строке, но опять же не работает через функцию PHP exec().

Спасибо за любую помощь, которую вы можете предложить.


person Matt McGuire    schedule 19.04.2017    source источник


Ответы (1)


Вы можете просто сделать это в PHP со стандартными функциями чтения файлов fopen() и другими:

<?php
$fname = "/var/log/nginx/access.log";
$pos = 0;
$matches = [];
$search = "foo";
$limit = 3;
$line = "";

$f = fopen($fname, "r");
while (fseek($f, $pos, SEEK_END) !== -1) {
    $char = fgetc($f);
    if ($char === PHP_EOL) {
        if (strpos($line, $search) !== false) {
            $matches[] = $line;
            if (count($matches) === $limit) {
                break;
            }
        }
        $line = '';
    } else {
            $line = "$char$line";
    }
    $pos--;
}
fclose($f);
print_r($matches);
person miken32    schedule 19.04.2017