Inotifywait cho số lượng lớn các tập tin trong một thư mục


7

Những gì tôi muốn làm là, để theo dõi một thư mục (không phải đệ quy, chỉ một) cho các tệp mới được tạo và nối các tệp đó vào một tệp lớn khi chúng được ghi.

Số lượng tệp đang được viết là rất lớn, có thể lên tới 50.000.

Bằng cách sử dụng inotifywait, tôi đang theo dõi thư mục như:

inotifywait -m -e create ~/folder | awk '($2=="CREATE"){print $3}' > ~/output.file

Vì vậy, tôi đang lưu trữ tên của các tệp mới được tạo ~/output.filevà sau đó sử dụng vòng lặp for

for FILE in `cat ~/output.file` 
do
    cat $FILE >> ~/test.out
done

Nó hoạt động tốt, nếu tốc độ mà một tệp đang được ghi (tạo) ~/foldergiống như 1 tệp mỗi giây.

Nhưng yêu cầu rất lớn và tốc độ tạo các tệp rất cao, như 500 tệp mỗi phút (hoặc thậm chí nhiều hơn).

Tôi đã kiểm tra số lượng tệp ~/foldersau khi quá trình hoàn tất, nhưng nó không khớp với inotifywaitđầu ra. Có một sự khác biệt giống như 10 tập tin1515, khác nhau.

Ngoài ra, vòng lặp

for FILE in `cat ~/output.file`
do
done

không xử lý tất cả các tệp trong ~/output.filekhi chúng đang được viết.

Bất cứ ai có thể xin vui lòng gợi ý cho tôi một giải pháp thanh lịch cho vấn đề này?

Câu trả lời:


6

Có một lý do cụ thể mà bạn đang sử dụng:

 | awk '($2=="CREATE"){print $3}' > ~/output.file

thay vì inotifywaitlựa chọn thích --format--outfile?

Nếu tôi chạy:

inotifywait -m --format '%f' -e create /home/don/folder/ --outfile /home/don/output.file

sau đó mở một tab khác, cdđến ~/foldervà chạy:

time seq -w 00001 50000 | parallel touch {}

real    1m44.841s
user    3m22.042s
sys     1m34.001s

(vì vậy tôi nhận được hơn 500 tệp mỗi phút) mọi thứ đều hoạt động tốt và output.filechứa tất cả các 50000tên tệp mà tôi vừa tạo.
Khi quá trình ghi xong các tệp vào đĩa, bạn có thể nối chúng vào test.out(giả sử bạn luôn ở trong ~/folder):

xargs < /home/don/output.file cat >> final.file

Hoặc sử dụng readnếu bạn muốn xử lý tệp khi chúng được tạo. Vì vậy, trong khi trong ~/folderbạn có thể chạy:

inotifywait -m --format '%f' -e create ~/folder | while read file; do cat -- "$file" >> ~/test.out; done

Lưu ý rằng trong inotifywaitổn định, -m-tkhông thể được sử dụng cùng nhau. Hỗ trợ cho việc sử dụng cả hai công tắc đã được thêm gần đây, vì vậy nếu bạn xây dựng inotify-toolstừ gitbạn sẽ có thể sử dụng monitorvới timeout(để chỉ định thời gian phải chờ một sự kiện thích hợp xảy ra trước khi thoát). Tôi đã thử nghiệm gitphiên bản trên hệ thống của mình (thoát nếu không có createsự kiện nào xảy ra trong vòng 2 giây) và nó hoạt động tốt:

inotifywait -m -t 2 --format '%f' -e create ~/folder | while read file; do cat -- "$file" >> ~/test.out; done

Tôi muốn làm những việc song song, để tiết kiệm thời gian. Tạo các tệp nhỏ và nối thêm chúng khi chúng được tạo. Vì vậy, awk sẽ lọc các tệp đã tạo từ tổng danh sách inotiify tạo.
rohitkulky

Hey don, điều này hoạt động tốt! Tôi đã đi qua điều này sớm hơn, nhưng không thể làm cho mọi thứ hoạt động bằng cách nào đó. Cảm ơn! :)
rohitkulky

Bạn có thể đặt bình luận này trong câu trả lời cho rõ ràng, vì lợi ích của người khác! :)
rohitkulky

xin lỗi để đưa nó lên muộn, kịch bản trên hoạt động tốt như tôi đã nói. Nhưng một khi quá trình tạo tập tin trong thư mục kết thúc, quá trình inotifywaitchạy vô thời hạn, vì vậy tôi phải giết quá trình bằng tay. Có cách nào để làm điều này một cách thanh lịch? Các --timeoutchờ đợi lựa chọn duy nhất cho sự kiện đầu tiên và sau đó thoát. Cảm ơn!
rohitkulky

@rohitvk - Bạn không thể sử dụng monitortimeoutcùng với phiên bản hiện tại, bạn sẽ phải cài đặt gitphiên bản. Trả lời cập nhật.
don_crissti

0

Một điều bạn có thể làm là tạo một chương trình nhỏ để di chuyển các tệp đã xử lý ra khỏi thư mục sang một thư mục khác sau khi chúng được xử lý. Chỉ cần khởi động lại quá trình quét thư mục sau khi bạn hoàn thành. Ngủ trong một khoảng thời gian hợp lý trước khi quét lại nếu không có tệp nào ở đó và thực hiện việc này trong suốt thời gian tạo tệp (quá trình tạo tệp dường như chỉ chạy trong tối đa 100 phút hoặc lâu hơn).

Nếu bạn không thể di chuyển các tệp từ thư mục, một cách tiếp cận khác là bắt đầu với một DTS có dấu thời gian ở đâu đó trong quá khứ. Sau đó tìm tất cả các tệp mới hơn DTS, xử lý chúng và cập nhật DTS nếu dấu thời gian của tệp mới hơn DTS. Lặp lại quá trình này như với giải pháp trên. Nếu độ chi tiết của dấu thời gian của bạn ngăn hai tệp có cùng một tệp, bạn chỉ có thể tìm các tệp mới hơn DTS. Nếu không, bạn phải tìm các tệp không cũ hơn DTS và giữ một danh sách các tệp có DTS bạn sẽ sử dụng trong lần chạy tiếp theo và lọc chúng ra trong lần chạy tiếp theo.

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.