1

У меня есть процесс, который выводит строку для каждого обновления прогресса (sidenote: он очищает / заменяет строку, без чистого перевода строки).

Я хочу сохранить последнюю строку этого процесса в выходной файл или обрезать выходной файл, чтобы сохранить размер управляемым.

На данный момент у меня есть genrtr > genrtr.log и с помощью cron я попытался использовать > genrtr.log но он не работает. Также rm genrtr.log не помогает, потому что тогда процесс перестает обновлять файл.

Я понимаю, почему они не работают, но удивляюсь, как это перестроить, чтобы оно соответствовало моим потребностям.

Попробовал genrtr | sed -ne '$w genrtr.log' но затем он ожидает завершения процесса перед записью в файл.

Пояснения: процесс выдает выходные данные каждую 1 секунду, и, если не произойдет сбой сервера, процесс будет работать вечно.

3 ответа3

0

мне было интересно, какова частота пробега? ....

попробуйте перенаправить вывод в файл журнала, это утилита, часто используемая для создания копии strem и перенаправления этой копии в выходной файл

use : 
  command | tee command_result.log 

у вас может быть функция монитора в скрипте-обёртке, которая вызывает эту программу, которая удалит первые 10 строк после некоторого интравала ....... таким образом, ваш файл журнала не получит больше, чем несколько КБ

также, если между ними есть бесполезные пробелы, вы можете использовать утилиту translate "tr", чтобы сжать ... пример :

Nitin@Kaizen ~
$ df -h | head -1
    Filesystem      Size  Used Avail Use% Mounted on

Nitin@Kaizen ~
$ df -h | head -1 | tr -s ' '
    Filesystem Size Used Avail Use% Mounted on   *** note the squeeze in space 

надеюсь это поможет

0

Есть несколько вещей, которые вы можете попробовать. Самое простое - просто напечатать последние строки файла:

tail genrtr.log

Затем, как только процесс завершится, удалите файл журнала. Другой вариант - периодически перезаписывать файл.

  • Запустите процесс в фоновом режиме:

    genrtr > genrtr.log &
    
  • Перезаписать содержимое файла журнала:

    echo > genrtr.log
    

Файл теперь обрезан, но будет обновляться программой gentr поэтому в него будет записан следующий отчет об обновлении. Вы можете автоматизировать это, например, обрезая файл, если он становится больше 1 МБ:

while true; 
  do if [ $(stat -c%s genrtr.log) -gt 1000000 ]; then 
    tail genrt.log > /tmp/foo && cat /tmp/foo > genrt.log; 
     fi;
done

Этот маленький скриптлет будет работать до тех пор, пока вы не остановите его (while true;), и каждый раз, когда genrtr.log будет превышать один МБ, он сохранит последние несколько строк и удалит остальную часть файла.


ОБНОВИТЬ:

Как Скотт очень правильно указал ниже, если ваш вывод содержит \r для очистки строки, tail не будет работать должным образом. Это, однако, должно:

while true; 
  do if [ $(stat -c%s genrtr.log) -gt 1000000 ]; then 
    tail genrt.log | perl -pe 's/.+\r(.+)/$1\n/' > /tmp/foo && cat /tmp/foo > genrt.log; 
     fi;
done

Команда perl удаляет все до последнего \r и печатает последнюю "строку" (данные после \r и новую строку. В результате строка списка сохраняется, остальная часть файла очищается и файл продолжает заполняться.

0

Я считаю, что это будет очень сложно обойтись без изменения genrtrc или написания новой программы.  Если вам удобнее делать последнее, я предлагаю следующую схему:

int   c;
FILE  *fp;

fp = fopen( log_file , "w");
if (fp == NULL) (обрабатывать ошибки)
while ((c = getc()) != EOF)
{
    putchar(c);
    if (c == escape-последовательность, которая заканчивается строкой )
    {
        fflush(fp);     // Вероятно, вам следует проверить здесь и ошибки.
        rewind(fp);
    }
    else
        putc(c, fp);
}

Это действует как комбинация tee и tail - чтение стандартного ввода и запись его в стандартный вывод и файл - с той разницей, что он сохраняет только последнюю строку в файле.  Тогда вы бы побежали

genrtr | the_above_program

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .