Необходимо найти последние обновленные записи в лог-файле

Вы создаете каталог с именем из $3, но создаете файл в текущем каталоге.

Чтобы создать файл в новом каталоге, просто перенаправьте на имя в этом каталоге:

mkdir "$3"
tr -dc 'A-Za-z0-9' </dev/urandom | head -c 255 >"$3/$(shuf -n 1 /usr/share/dict/french)"

Или, чтобы разделить вещи для удобства чтения:

dir=$3

mkdir -p -- "$dir" || exit 1

fname=$(shuf -n 1 /usr/share/dict/french)

tr -dc 'A-Za-z0-9' </dev/urandom | head -c 255 >"$dir/$fname"

Здесь я также убедился, что если $3содержит пути с несуществующими подкаталогами, полный путь создается (путем добавления -pк вызову mkdir; что также делаетmkdirне неудачным, если путь уже существует ). Я также добавляю к пути префикс--на тот случай, если первый символ в $3— это -(, в противном случае это может привести к путанице mkdir; --сигнализирует об окончании параметров командной строки ). Я также выхожу с нулевым статусом выхода, отличным от -, если вызов mkdirне удался.

0
05.03.2020, 22:40
1 ответ

Вы можете использовать эту 41-строчную программу TXR Lisp в качестве демона для мониторинга файла журнала и создания его версии с отметками времени в режиме реального времени.

TXR имеет очень мало зависимостей и небольшой объем памяти, но при этом обладает широкими возможностями.

Во-первых, демо:

Мы начинаем с состояния, в котором fooи barне существуют. fooбудет файл журнала без штампов. barбудет файл журнала с отметками:

$ rm -f foo bar

Мы запускаем программу stamp.tlв фоновом режиме. Я не добавлял в него#!(решетку )строку (упражнение для читателя ), поэтому мы используем txr. -dозначает, что он перейдет в фоновый режим как демон :

.
$ txr stamp.tl -d foo bar

Хорошо, давайте начнем создавать контент вfoo:

$ echo "first post" >> foo
$ cat foo
first post

Что происходит в bar?

$ cat bar
2021-08-20 06:40:06 first post

Строка журнала появилась там с отметкой времени. Продолжай:

$ echo "second post" >> foo
$ cat bar
2021-08-20 06:40:06 first post
2021-08-20 06:40:17 second post
$ echo "third post" >> foo
$ cat bar
2021-08-20 06:40:06 first post
2021-08-20 06:40:17 second post
2021-08-20 06:40:24 third post

Теперь давайте попробуем кое-что. Предположим, что программное обеспечение, записывающее журнал foo, ротирует журнал. fooисчезает, а затем снова начинается с нулевой длины:

$ rm foo
$ echo "rotated" >> foo
$ cat foo
rotated

Что происходит с bar?

$ cat bar
2021-08-20 06:40:06 first post
2021-08-20 06:40:17 second post
2021-08-20 06:40:24 third post
2021-08-20 06:40:49 rotated

Как видите, он отлично захватил строку rotated.

Конечно, реальное решение состоит в том, чтобы исправить оригинальное программное обеспечение, которое ведет журнал без временных меток, но пока это может быть просто решением группы -.

Далее следует код. Программа имеет три варианта. В дополнение к приведенному выше -d, который мы использовали,у него есть возможность перезаписать целевой файл (поведение по умолчанию — добавить )и возможность использовать полную буферизацию для записи (по умолчанию — использовать буферизацию строк ).

Обратите внимание, что программа не поддерживает ротацию выходного журнала, потому что она просто открывает файл и оставляет его открытым. Чтобы поддерживать внешнюю ротацию журналов, программе пришлось бы открывать и закрывать файл каждый раз, когда он записывает. Или же реализовать внутреннее вращение :после такого количества строк, закрыть файл, выполнить вращающееся переименование и повторно -открыть его.

;; Copyright 2021
;; Kaz Kylheku <kaz@kylheku.com>
;; Vancouver, Canada
;; All rights reserved.
;;
;; Redistribution and use in source and binary forms, with or without
;; modification, are permitted provided that the following conditions are met:
;;
;; 1. Redistributions of source code must retain the above copyright notice,
;;    this list of conditions and the following disclaimer.
;;
;; 2. Redistributions in binary form must reproduce the above copyright notice,
;;    this list of conditions and the following disclaimer in the documentation
;;    and/or other materials provided with the distribution.
;;
;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
;; POSSIBILITY OF SUCH DAMAGE.

(defun stamp (infile outfile opts)
  (when (and opts.daemonize
             (not (daemon t nil))) ;; don't chdir
    (put-line "failed to daemonize")
    (exit nil))
  (let* ((line-buf (if opts.fully-buffered "" "l"))
         (write-mode (if opts.overwrite `w@{line-buf}` `a@{line-buf}`)))
    (with-resources ((out (open-file outfile write-mode) (close-stream out))
                     (in (open-tail infile) (close-stream in)))
      (whilet ((line (get-line in)))
        (let ((stamp (time-string-local (time) "%Y-%m-%d %H:%M:%S")))
          (put-line `@stamp @line` out))))))

(define-option-struct prog-opts nil
  (w   overwrite        :bool
       "Overwrite the output file instead of appending.")
  (d   daemonize        :bool
       "Run in the background as a daemon")
  (f   fully-buffered   :bool
       "Writes to the output file are flushed whenever\ \
        an I/O buffer fills up. The default behavior is to\ \
        flush after every line.")
  (nil help    :bool
       "List this help text."))

(defvarl prog-name *load-path*)

(defun usage ()
  (put-line "\nUsage:\n")
  (put-line `  @{prog-name} [ options ] <infile> [ <outfile> ]`))

(let ((o (new prog-opts)))
  o.(getopts *args*)
  (when o.help
    (usage)
    o.(opthelp)
    (exit nil))
  (match-case o.out-args
    ((@infile @outfile) (stamp infile outfile o))
    ((@infile) (stamp infile `@infile.stamped` o))
    (@else (usage) (exit nil))))
0
20.08.2021, 20:54

Теги

Похожие вопросы