commit 17c6e87a89ff91eef0eee5d37861b54d433d8874 Author: Peter J. Holzer Date: Sat Dec 18 01:59:22 2021 +0100 Watch a directory and tail all files diff --git a/kitsune b/kitsune new file mode 100755 index 0000000..82ed4bf --- /dev/null +++ b/kitsune @@ -0,0 +1,64 @@ +#!/usr/bin/python3 + +import datetime +import os +import sys +import time + +class WatchedFile: + def __init__(self, name): + self.name = name + self.reopen() + + def reopen(self): + self.fd = open(self.name, errors='replace') + self.fileno = self.fd.fileno() + self.last_ts = 0 + +def format_ts(ts_ns): + return datetime.datetime.fromtimestamp(ts_ns / 1E9).strftime("%H:%M:%S.%f") + +def watch(dir): + os.chdir(dir) + last_ts = 0 + watched_files = {} + filename_length = 0 + while True: + # are there new files? + st = os.stat(".") + if st.st_mtime_ns > last_ts: + last_ts = st.st_mtime_ns + for de in os.scandir("."): + if de.is_file(): + if de.name not in watched_files: + watched_files[de.name] = WatchedFile(de.name) + if len(de.name) > filename_length: + filename_length = len(de.name) + + # has any of the files changed + for f in watched_files.values(): + # XXX - we should also detect replaced files. + st = os.stat(f.fileno) + try: + stf = os.stat(f.name) + if stf.st_ino != st.st_ino: + f.reopen() + except FileNotFoundError: + # ignore, + # or maybe remove from watched_files? + # or just mark as deleted? + pass + if st.st_mtime_ns > f.last_ts: + f.last_ts = st.st_mtime_ns + new_content = f.fd.read() + lines = new_content.split("\n") + if lines[-1] == "": + lines.pop() + for ln in lines: + print(f"{f.name:{filename_length}}", format_ts(f.last_ts), ln) + time.sleep(0.1) + +if __name__ == "__main__": + dir = sys.argv[1] if len(sys.argv) > 1 else "." + + watch(dir)