слідкуйте за файлами (à la tail -f) у всій каталозі (навіть у нових)


53

Я звичайно спостерігаю, як багато журналів у каталозі роблять tail -f directory/*. Проблема полягає в тому, що після цього створюється новий журнал, він не відображатиметься на екрані (тому що *він уже розширений).

Чи є спосіб відстежувати кожен файл у каталозі, навіть той, який створюється після запуску процесу?

Відповіді:


44

Ви можете створити хвіст кількох файлів за допомогою ... багатоповерхівки .

multitail -Q 1 'directory/*'

-Q 1 PATTERNозначає перевіряти наявність нового вмісту в існуючих або нових файлах, що відповідають PATTERN кожні 1 секунду. Рядки з усіх файлів відображаються в одному вікні, використовуйте -qзамість того, -Qщоб мати окремі вікна.


10

xtailтакож є альтернативою. Сторінка людини описує це як:

Xtail відстежує один або кілька файлів і відображає всі дані, записані у файл з моменту виклику команди. Це дуже корисно для моніторингу декількох журналів одночасно. Якщо запис у командному рядку є каталогом, всі файли в цьому каталозі будуть контролюватися, включаючи файли, створені після виклику xtail. Якщо запису, вказаного в командному рядку, не існує, xtail буде стежити за ним та відстежувати його після створення. Під час перемикання файлів на дисплеї друкується банер із зазначенням імені шляху файлу.

Символ переривання (зазвичай CTRL / C або DEL) відображатиме список останніх змінених файлів, які переглядаються. Надішліть сигнал виходу (як правило, CTRL / зворотній косий ривок), щоб зупинити xtail.


1
Посилання розірвано, але я думаю, це те саме, що: manpages.ubuntu.com/manpages/zesty/man1/xtail.1.html
edpaez

7

Поняття про рішення оболонки не маю, але (припустимо, що Linux 1) inotifyможе бути шляхом ... див. Цей приклад, що імітуєtail -F (використовуючи pyinotify), можливо, він може бути використаний як основа для перегляду всього каталогу .

Взагалі, inotifyможна контролювати каталоги (цитуючи man 7 inotify)

Наступні біти можуть бути вказані в масці під час виклику inotify_add_watch (2) і можуть бути повернуті в поле маски, повернене читанням (2):

IN_ACCESS         File was accessed (read) (*).
IN_ATTRIB         Metadata changed, e.g., permissions, timestamps,
                    extended attributes, link count (since Linux 2.6.25),
                    UID, GID, etc. (*).
IN_CLOSE_WRITE    File opened for writing was closed (*).
IN_CLOSE_NOWRITE  File not opened for writing was closed (*).
IN_CREATE         File/directory created in watched directory (*).
IN_DELETE         File/directory deleted from watched directory (*).
IN_DELETE_SELF    Watched file/directory was itself deleted.
IN_MODIFY         File was modified (*).
IN_MOVE_SELF      Watched file/directory was itself moved.
IN_MOVED_FROM     File moved out of watched directory (*).
IN_MOVED_TO       File moved into watched directory (*).
IN_OPEN           File was opened (*).

Під час моніторингу каталогу , події, позначені зірочкою (*) вище, можуть відбуватися для файлів у каталозі; у цьому випадку поле імені у поверненій структурі inotify_event ідентифікує ім’я файлу в каталозі.

(... і pyinotifyуважно слідує варіантам тези)

1: BSDs є щось подібне, kqueue. Можливо, рішення для платформи можливо досягти, використовуючи GIO (зв'язки Python ) як шар абстракції, оскільки він, крім того inotify, може також використовуватиkqueue


2

Я написав швидкий, який задовольняє потребу.

#!/bin/bash
LOG_PATTERN=$1
BASE_DIR=$(dirname $LOG_PATTERN* | head -1)

run_thread (){
    echo Running thread
    tail -F $LOG_PATTERN* &
    THREAD_PID=$!
}

# When someone decides to stop the script - killall children
cleanup () {
    pgrep -P $$ | xargs -i kill {}
    exit
}

trap cleanup SIGHUP SIGINT SIGTERM

if [ $# -ne 1 ]; then
    echo "usage: $0 <directory/pattern without * in the end>"
    exit 1
fi

# Wait for the directory to be created
if [ ! -d $BASE_DIR ] ; then
    echo DIR $BASE_DIR does not exist, waiting for it...
    while [ ! -d $BASE_DIR ] ; do
        sleep 2
    done
    echo DIR $BASE_DIR is now online
fi

# count current number of files
OLD_NUM_OF_FILES=$(ls -l $LOG_PATTERN* 2>/dev/null | wc -l)

# Start Tailing
run_thread

while [ 1 ]; do
    # If files are added - retail
    NUM_FILES=$(ls -l $LOG_PATTERN* 2>/dev/null | wc -l)
    if [ $NUM_FILES -ne $OLD_NUM_OF_FILES ]; then
        OLD_NUM_OF_FILES=$NUM_FILES
        kill $THREAD_PID
        run_thread
    fi
    sleep 1
done

1
Власне, ви можете опустити сон 1 в основному циклі, буде більш спритним отримати нові файли. Але мені не подобається таке напружене очікування
Ітамар

У зв'язку з sleepцим це не зайняте очікування, але м'яке на процесорі, просто опитування. Можна змінити його на sleep 0.2s(сон GNU) або що інше, щоб прискорити його швидше.
Ned64

2

Також ви можете дивитися каталог із watch

watch -n0,1 "ls -lrt /directory/ | tail"

Незначний ніткоп: watchперемальовує екран в альтернативному буфері з першими x рядками виведення з команди. У ряді файлів без змін, якщо попередні файли не змінюються, вони tailможуть робити те саме, щоразу, так що ви не матимете жодних додаткових записів, оскільки вони малюються в пізніших файлах "внизу" внизу екран. Однак для короткого файлу це добре ...
jimbobmcgee

Це не дає вирішення вихідної проблеми. Це лише виводить (останні кілька рядків) список каталогів (неодноразово, завжди актуальний - завдяки watch), замість останніх рядків усіх файлів (включаючи нові) у цьому каталозі.
тр
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.