import sys import argparse from collections import deque def handle_print(source, count, is_bytes): if is_bytes: decoded = bytearray(deque(source, count)).decode('utf-8') print(decoded) else: for l in deque(source, count): print(l, end="") def tail(filename, count, is_bytes=False): if filename: try: if is_bytes: with open(filename, 'rb') as f: handle_print(f.read(), count, is_bytes) else: with open(filename, 'r') as f: handle_print(f, count, is_bytes) except FileNotFoundError: print("File not found!") exit(1) else: source = sys.stdin if is_bytes: source = source.buffer.read() handle_print(source, count, is_bytes) def positive_int(arg): try: val = int(arg) except ValueError: raise argparse.ArgumentTypeError("Must be an integer") if val < 0: raise argparse.ArgumentTypeError("Must be greater than or equal to 0") return val def parse_arguments(): parser = argparse.ArgumentParser() parser.add_argument("--lines", type=positive_int, default=10, help="Number of lines to read from the end") parser.add_argument("--bytes", type=positive_int, nargs="?", help="Number of bytes to read from the end", ) parser.add_argument("filename", nargs="?", help="Path of the file to be read") return parser.parse_args() def main(args): if args.bytes is not None: tail(args.filename,args.bytes, True) else: tail(args.filename, args.lines) if __name__ == "__main__": args = parse_arguments() main(args)