I took the answer from @Ulfalizer and expanded it a bit to be a complete and usable app.
import sysimport fcntlimport termiosimport argparseparser = argparse.ArgumentParser()parser.add_argument('tty', type=argparse.FileType('w'), help='full tty path as given by the tty command')group = parser.add_mutually_exclusive_group()group.add_argument('-n', action='store_true', help='prevent sending a trailing newline character')group.add_argument('--stdin', action='store_true', help='read input from stdin')group = parser.add_argument_group()group.add_argument('cmd', nargs='?', help='command to run (required if not using --stdin)')group.add_argument('args', nargs='*', help='arguments to command')args = parser.parse_known_args()if args.stdin: data = sys.stdin.read()else: data = ''.join([args.cmd] + args.args)for c in data: fcntl.ioctl(args.tty, termios.TIOCSTI, c)if not args.n and data[-1][-1] != '\n': fcntl.ioctl(args.tty, termios.TIOCSTI, '\n')
Here is how you use it:
Terminal #1: do...
$ tty > /tmp/t1
Terminal #2: do...
$ sudo python termfake.py $(cat /tmp/t1) date +%s
Terminal #1: observe...
$ tty > /tmp/t1$ date +%s1487276400