import termios import tty import sys def interactive_read(): """Reads characters one by one until 'q' is pressed, then restores terminal.""" # 1. Get the file descriptor for standard input fd = sys.stdin.fileno() # 2. Get and make a COPY of the current terminal attributes # The termios functions operate on this list structure: [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] old_settings = termios.tcgetattr(fd) print("Terminal in default mode. Press Enter to continue to Cbreak mode...") sys.stdin.readline() # Read until Enter is pressed try: # 3. Enter Cbreak mode # tty.setcbreak is a helper that calls tcsetattr for you. # By default, tty.setcbreak uses termios.TCSAFLUSH! tty.setcbreak(fd, termios.TCSAFLUSH) print("Terminal now in Cbreak mode. Press 'q' to quit.") while True: # Read a single character immediately char = sys.stdin.read(1) if char == 'q': break print(f"You pressed: {repr(char)}") # repr shows things like '\n' for safety except Exception as e: print(f"An error occurred: {e}") finally: # 4. CRITICAL: Restore the original settings using TCSAFLUSH # We use TCSAFLUSH here to discard any half-typed input # that might have occurred while we were in cbreak mode. termios.tcsetattr(fd, termios.TCSAFLUSH, old_settings) print("\nTerminal settings restored. Goodbye!") if __name__ == "__main__": # The termios module only works on Unix-like systems. if sys.platform.startswith('linux') or sys.platform.startswith('darwin'): interactive_read() else: print("This script uses termios, which is only available on Unix-like systems.")