giám sát các tệp (à la tail -f) trong toàn bộ thư mục (ngay cả những tệp mới)


53

Tôi thường xem nhiều nhật ký trong một thư mục đang làm tail -f directory/*. Vấn đề là một bản ghi mới được tạo sau đó, nó sẽ không hiển thị trên màn hình (vì *đã được mở rộng).

Có cách nào để giám sát mọi tập tin trong một thư mục, ngay cả những tập tin được tạo sau khi quá trình đã bắt đầu không?

Câu trả lời:


44

Bạn có thể theo đuôi nhiều tệp ple với multitail .

multitail -Q 1 'directory/*'

-Q 1 PATTERNcó nghĩa là kiểm tra nội dung mới trong các tệp hiện có hoặc mới phù hợp với MẪU cứ sau 1 giây. Các dòng từ tất cả các tệp được hiển thị trong cùng một cửa sổ, sử dụng -qthay vì -Qđể có các cửa sổ riêng biệt.


10

xtailcũng là một thay thế. Trang người đàn ông của nó mô tả nó như sau:

Xtail giám sát một hoặc nhiều tệp và hiển thị tất cả dữ liệu được ghi vào tệp kể từ khi gọi lệnh. Nó rất hữu ích để theo dõi nhiều logfiles cùng một lúc. Nếu một mục được đưa ra trên dòng lệnh là một thư mục, tất cả các tệp trong thư mục đó sẽ được theo dõi, bao gồm cả các mục được tạo sau khi gọi xtail. Nếu một mục nhập được đưa ra trên dòng lệnh không tồn tại, xtail sẽ theo dõi nó và theo dõi nó một khi được tạo. Khi chuyển đổi tập tin trong màn hình, một biểu ngữ hiển thị tên đường dẫn của tập tin được in.

Một ký tự ngắt (thường là CTRL / C hoặc DEL) sẽ hiển thị danh sách các tệp được sửa đổi gần đây nhất đang được xem. Gửi tín hiệu thoát (thường là CTRL / dấu gạch chéo ngược) để dừng xtail.


1
Liên kết bị hỏng, nhưng tôi nghĩ là giống như: manpages.ubfox.com/manpages/zesty/man1/xtail.1.html
edpaez

7

Không có ý tưởng nào về giải pháp hệ vỏ, nhưng (giả sử Linux 1) inotifycó thể là cách để ... xem ví dụ này bắt chướctail -F (sử dụng pyinotify), có thể nó có thể được sử dụng làm cơ sở để theo dõi toàn bộ thư mục .

Nói chung, inotifycó thể theo dõi các thư mục (trích dẫn man 7 inotify)

Các bit sau có thể được chỉ định trong mặt nạ khi gọi inotify_add_watch (2) và có thể được trả về trong trường mặt nạ được trả về bởi 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 (*).

Khi theo dõi một thư mục , các sự kiện được đánh dấu hoa thị (*) ở trên có thể xảy ra đối với các tệp trong thư mục, trong trường hợp đó, trường tên trong cấu trúc inotify_event được trả về sẽ xác định tên của tệp trong thư mục.

(... Và pyinotifytheo sát các tùy chọn luận án)

1: BSD có một điều tương tự , kqueue. Có lẽ một giải pháp đa nền tảng được sử dụng có thể đạt được GIO ( bindings Python ) là lớp trừu tượng vì nó có thể, bên cạnh inotify, cũng sử dụngkqueue


2

Tôi đã viết một cái nhanh chóng đáp ứng nhu cầu.

#!/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
Trên thực tế, bạn có thể sử dụng chế độ ngủ 1 trong vòng lặp chính, sẽ trở nên gọn gàng hơn để có được các tệp mới. Nhưng tôi không thích kiểu chờ đợi bận rộn đó
Itamar

Do sleepđây không phải là một sự chờ đợi bận rộn mà là CPU mềm, chỉ cần bỏ phiếu. Người ta có thể thay đổi nó thành sleep 0.2s(ngủ GNU) hoặc bất cứ điều gì để làm cho nó nhanh hơn nếu được yêu cầu.
Ned64

2

Ngoài ra, bạn có thể xem thư mục với watch

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

Mã khóa nhỏ: watchvẽ lại màn hình trong bộ đệm thay thế, với x dòng đầu ra từ lệnh. Trên một số tệp không có thay đổi, nếu các tệp trước đó không thay đổi, mỗi lần tailcó thể hiển thị cùng một thứ, do đó bạn sẽ không có sự xuất hiện của các mục bổ sung, vì chúng được vẽ trong các tệp sau 'bên dưới' dưới cùng của màn. Tuy nhiên, đối với một tệp ngắn, điều này vẫn ổn ...
jimbobmcgee

Điều này không đưa ra một giải pháp cho vấn đề ban đầu. Điều này chỉ xuất ra (một vài dòng cuối cùng) một danh sách thư mục (lặp đi lặp lại, luôn luôn hiện hành - nhờ watch), thay vì các dòng mới nhất của tất cả các tệp (bao gồm cả các tệp mới) trong thư mục đó.
trs
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.