ディレクトリ全体(新しいものも含む)でファイルを監視します(tail -f)


53

私は通常、ディレクトリ内の多くのログを見ていtail -f directory/*ます。問題は、その後に新しいログが作成され、画面に表示されないことです(*すでに展開されているため)。

プロセスの開始後に作成されたファイルも含め、ディレクトリ内のすべてのファイルを監視する方法はありますか?

回答:


43

次のことができ マルチで... PLEファイルをmultitail

multitail -Q 1 'directory/*'

-Q 1 PATTERNPATTERNに一致する既存または新しいファイルの新しいコンテンツを1秒ごとにチェックすることを意味します。すべてのファイルの行は同じウィンドウに表示されますが、-q代わりに-Q別のウィンドウを使用します。


10

xtail代替手段でもあります。そのmanページでは、次のように説明しています。

Xtailは1つ以上のファイルを監視し、コマンド呼び出し以降にファイルに書き込まれたすべてのデータを表示します。複数のログファイルを同時に監視するのに非常に便利です。コマンドラインで指定されたエントリがディレクトリである場合、xtailの呼び出し後に作成されたファイルを含む、そのディレクトリ内のすべてのファイルが監視されます。コマンドラインで指定されたエントリが存在しない場合、xtailはそれを監視し、作成されたエントリを監視します。ディスプレイでファイルを切り替えると、ファイルのパス名を示すバナーが印刷されます。

割り込み文字(通常はCTRL / CまたはDEL)は、監視されている最新の変更されたファイルのリストを表示します。終了シグナル(通常はCTRL /バックスラッシュ)を送信して、xtailを停止します。


1
リンクが壊れていますが、私は同じと思います:manpages.ubuntu.com/manpages/zesty/man1/xtail.1.html
edpaez

7

いいえシェル溶液についての考えませんが、(Linuxの仮定1inotify...行くための方法かもしれ模倣この例を参照してくださいtail -F(使用してpyinotify多分それはのための基礎として使用することができ、)ディレクトリ全体を次のよう

一般に、inotifyディレクトリを監視できます(引用man 7 inotify

次のビットは、inotify_add_watch(2)を呼び出すときにmaskで指定でき、read(2)によって返されるmaskフィールドで返される場合があります。

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:BSDにも似たようなものがあり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を省略することができ、新しいファイルを取得するのがより簡単になります。しかし、私はそのような忙しい待機が好きではありません
-Itamar

ためにsleep、このビジーウェイトが、CPU上のソフト、ただポーリングではありません。sleep 0.2s必要に応じて、それを(GNUスリープ)またはその他のものに変更して、高速化することができます。
Ned64

2

また、あなたはでディレクトリを見ることができます watch

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

マイナーピック:コマンドからの出力のwatch最初のx行を使用して、代替バッファーに画面を再描画します。変更のない多数のファイルにわたって、以前のファイルが変更されない場合、tail毎回同じものがレンダリングされる可能性があるため、追加のエントリがないように見えます。画面。ただし、短いファイルの場合、これは問題ありません
...-jimbobmcgee

これは、元の問題の解決策にはなりません。これwatchは、そのディレクトリ内のすべてのファイル(新しいファイルを含む)の最新行ではなく、ディレクトリ一覧(最後の数行)を出力するだけです(繰り返し、常に最新です-のおかげです)。
trs
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.