How to emulate sending keystrokes through a terminal program

inputinput-methodkeyboardterminal

I need to send keystrokes virtually to a terminal program (like vi or emacs).

I want to do something like this:

echo -e 'iHello, world!\e' | vi

and then have a vi session open with this buffer:

Hello, world!
~
~
~
~
~

But that does not work as vi does not read keystrokes through stdin.

I get this error:

ex/vi: Vi's standard input and output must be a terminal

How can I send some text string to a terminal program as if the string was typed directly on a keyboard?

Best Answer

That's typically what expect was written for:

expect -c 'spawn -noecho vi; send "iHello World!\r\33"; interact'

While expect was written for TCL in days prior to perl or python being popular, now similar modules for perl or python are also available.

Another option is to issue TIOCSTI ioctls to your tty device to insert characters (one byte at a time) in its input queue:

perl -le 'require "sys/ioctl.ph";
          ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV
         ' $'iHello World!\r\e'; vi

That has the benefit of avoiding an extra pseudo-terminal layer in between your terminal emulator and the application (here vi).

Related Question