surveiller les fichiers (à la queue -f) dans un répertoire complet (même les nouveaux)


53

Je regarde normalement de nombreux journaux dans un répertoire en train de faire tail -f directory/*. Le problème est qu'un nouveau journal est créé après cela, il ne s'affichera pas à l'écran (car *a déjà été développé).

Existe-t-il un moyen de surveiller chaque fichier d'un répertoire, même ceux créés après le démarrage du processus?

Réponses:


44

Vous pouvez queue plusieurs fichiers PLE avec ... multitail .

multitail -Q 1 'directory/*'

-Q 1 PATTERNsignifie vérifier si le nouveau contenu des fichiers existants ou nouveaux correspond à PATTERN toutes les 1 secondes. Les lignes de tous les fichiers sont affichées dans la même fenêtre, utilisez -qplutôt que d’ -Qavoir des fenêtres séparées.


10

xtailest aussi une alternative. Sa page de manuel le décrit comme:

Xtail surveille un ou plusieurs fichiers et affiche toutes les données écrites dans un fichier depuis l'invocation de la commande. C'est très utile pour surveiller plusieurs fichiers journaux simultanément. Si une entrée indiquée sur la ligne de commande est un répertoire, tous les fichiers de ce répertoire seront surveillés, y compris ceux créés après l'invocation de xtail. Si une entrée donnée sur la ligne de commande n'existe pas, xtail la surveillera et la surveillera une fois créée. Lors du changement de fichier à l’affichage, une bannière indiquant le chemin du fichier est imprimée.

Un caractère d'interruption (généralement CTRL / C ou DEL) affichera une liste des derniers fichiers modifiés visionnés. Envoyer un signal de sortie (généralement CTRL / backslash) pour arrêter xtail.


1
Le lien est cassé, mais je pense est le même que: manpages.ubuntu.com/manpages/zesty/man1/xtail.1.html
edpaez

7

Aucune idée sur une solution shell, mais (en supposant que Linux 1) inotifypourrait être la voie à suivre ... voyez cet exemple imitertail -F (utiliser pyinotify), peut-être qu'il peut être utilisé comme base pour suivre un répertoire entier .

En général, inotifypeut surveiller les répertoires (citant man 7 inotify)

Les bits suivants peuvent être spécifiés dans mask lors de l'appel de inotify_add_watch (2) et peuvent être renvoyés dans le champ de masque renvoyé par read (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 (*).

Lors de la surveillance d'un répertoire , les événements marqués d'un astérisque (*) ci-dessus peuvent se produire pour les fichiers du répertoire. Dans ce cas, le champ de nom de la structure inotify_event renvoyée identifie le nom du fichier dans le répertoire.

(... et pyinotifysuit de près ces options)

1: BSDs ont une chose semblable, kqueue. Peut-être qu'une solution multiplate-forme est réalisable en utilisant GIO ( liaisons Python ) comme couche d'abstraction puisqu'elle peut, à côté inotify, également utiliserkqueue


2

J'ai écrit un rapide qui répond au besoin.

#!/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
En fait, vous pouvez omettre le sommeil 1 dans la boucle principale, cela sera plus rapide pour obtenir de nouveaux fichiers. Mais je n'aime pas ce genre d'attentes occupées
Itamar le

En raison de sleepce n'est pas une attente occupée, mais soft sur le CPU, il suffit de scruter. On pourrait le changer en sleep 0.2s(sommeil GNU) ou autre pour le rendre plus rapide si nécessaire.
Ned64

2

Aussi, vous pouvez regarder le répertoire avec watch

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

Minor nitpick: watchredessine l'écran dans le tampon alternatif, avec les x premières lignes de sortie de la commande. Dans un certain nombre de fichiers sans modification, si les fichiers précédents ne sont pas modifiés, il est possible tailque la même chose soit rendue à chaque fois. écran. Cela ne
pose pas de problème

Cela ne donne pas de solution au problème initial. Cela affiche simplement (les dernières lignes de) une liste de répertoires (à plusieurs reprises, toujours actuelle - grâce à watch), à la place des dernières lignes de tous les fichiers (y compris les nouveaux) de ce répertoire.
Très
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.