Unable to fake terminal input with termios.TIOCSTI

前端 未结 2 620
北恋
北恋 2020-12-15 01:47

Most of the code samples I\'ve seen are trying to read from stdin without local echo. To do this they modify the \"local modes\" flag to remove the setting to \"Echo input c

2条回答
  •  有刺的猬
    2020-12-15 02:31

    I took the answer from @Ulfalizer and expanded it a bit to be a complete and usable app.

    import sys
    import fcntl
    import termios
    import argparse
    
    parser = 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 +%s
    1487276400
    

提交回复
热议问题