dosyaları (à la tail -f) bütün bir dizinde (hatta yenilerini de) izle


53

Normalde bir dizinde çok sayıda günlük izliyorum tail -f directory/*. Sorun şu ki, yeni bir günlük bundan sonra oluşturuldu, ekranda görünmeyecek (çünkü *zaten genişletildi).

Bir dizindeki her dosyayı, işlem başladıktan sonra oluşturulanları bile izlemenin bir yolu var mı?

Yanıtlar:


44

Şunları yapabilirsiniz kuyruk çoklu ile ... ple dosyaları multitail .

multitail -Q 1 'directory/*'

-Q 1 PATTERNher 1 saniyede PATTERN ile eşleşen mevcut veya yeni dosyalardaki yeni içeriği kontrol etmek anlamına gelir . Tüm dosyalardan satırlar aynı pencerede gösterilir , ayrı pencerelere sahip olmak -qyerine kullanın -Q.


10

xtailaynı zamanda bir alternatif. Man sayfası onu şöyle açıklar:

Xtail bir veya daha fazla dosyayı izler ve komut çağırılmasından bu yana bir dosyaya yazılan tüm verileri görüntüler. Aynı anda birden fazla günlük dosyasını izlemek için çok kullanışlıdır. Komut satırında verilen bir giriş bir dizin ise, bu dizindeki tüm dosyalar, xtail çağrısından sonra oluşturulanlar da dahil olmak üzere izlenecektir. Komut satırında verilen bir giriş yoksa, xtail bunu izler ve oluşturulduktan sonra onu izler. Ekrandaki dosyaları değiştirirken, dosyanın yol adını gösteren bir afiş yazdırılır.

Bir kesme karakteri (genellikle CTRL / C veya DEL) izlenen en son değiştirilen dosyaların bir listesini görüntüler. Xtail'ı durdurmak için bir çıkış sinyali (genellikle CTRL / ters eğik çizgi) gönderin.


1
Bağlantı kırık, ama aynı şekilde olduğunu düşünüyorum: manpages.ubuntu.com/manpages/zesty/man1/xtail.1.html
edpaez

7

Bir kabuk çözümü hakkında hiçbir fikrim yok, ancak (Linux varsayarsak 1) inotifygidilecek yol olabilir ... taklit edentail -F (kullanarak pyinotify) bu örneğe bakın , belki bir dizinin tamamını izlemek için bir temel olarak kullanılabilir .

Genel olarak, inotifydizinleri izleyebilir (kaynak gösterme man 7 inotify)

İnotify_add_watch (2) çağrılırken aşağıdaki bitler maskede belirtilebilir ve read (2) tarafından döndürülen maske alanına geri döndürülebilir:

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 (*).

Bir dizini izlerken , yukarıda (*) işaretli olaylar, dizindeki dosyalar için meydana gelebilir; bu durumda, iade edilen inotify_event yapısındaki isim alanı, dizindeki dosyanın adını tanımlar.

(... ve pyinotifytez seçeneklerini yakından takip ediyor)

1: BSD'lerin de benzer bir şeyi var kqueue. Belki de bir çapraz platform çözeltisi elde GIO (kullanan Python bağlantıları bu yanında çünkü soyutlama katmanı gibi) inotify, aynı zamanda kullanımıkqueue


2

İhtiyacı karşılayan hızlı bir tane yazdım.

#!/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
Aslında, ana döngüde uyku 1 atlayabilir, yeni dosyaları almak için daha çabuk olacaktır. Ama bu tür meşgul beklemekten hoşlanmıyorum
Itamar

Bunun nedeni sleepyoğun bir bekleyiş değil, CPU üzerinde yumuşak bir sorgulamadır. Kişi bunu sleep 0.2s(GNU uykusu) olarak değiştirebilir ya da gerekirse daha hızlı hale getirmek için ne yapabilirse.
Ned64,

2

Ayrıca dizini izleyebilirsiniz. watch

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

Minor nitpick: watchKomuttaki ilk x çıktı satırıyla , ekranı alternatif tamponda yeniden çizer . Değişiklik yapılmayan bir dizi dosya arasında, önceki dosyalar değişmezse, tailher seferinde aynı şeyi yapabilir, böylece daha sonraki dosyalarda 'altındaki' çizildikleri için hiçbir ek giriş görünmez. ekran. Kısa bir dosya için olsa, bu iyi ...
jimbobmcgee

Bu, orijinal soruna bir çözüm getirmez. Bu, dizindeki watchtüm dosyaların (yeniler dahil) en son satırlarının (dizinlerin son satırları) bir dizini listeleyebilmesini (tekrarlanan, her zaman güncel - sayesinde ) verir.
trs
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.