I'm trying to inject keystrokes into the input daemon so as to simulate typing from a Bash script. Is this possible, and if so, how can I make it happen?
Linux – How to Inject Keystrokes via a Shell Script
inputkeyboardlinuxshell-script
Related Solutions
GUI programs don't read from their standard input, they get their input from the X server. There are tools to inject a keystroke to a window. xdotool is fairly common and convenient.
You'll need to find the window ID that you want to send the keystroke to. You can do that with xdotool. xdotool search --class Chrome
returns the list of window IDs of all the Chrome windows. If this returns more than one, you need to pick the one you want. You can use xdotool search --name
to match on the title instead of the class. You can also parse the output of wmctrl and extract the desired window ID.
Once you've found the right window ID, you can call xdotool
to inject a keystroke. Unfortunately, many applications reject synthetic events, i.e. keystrokes and mouse events sent by another application. This is the case with current versions of Chrome. It's possible to inject a keystroke from another application by a different mechanism, but that requires the window to be focused. You can do all of that with xdotool, but it'll cause the focus to quickly flicker to the Chrome window and back. The following snippet sends F5 to the first Chrome window (in a somewhat arbitrary order).
xdotool search --class Chrome windowactivate --sync %1 key F5 windowactivate $(xdotool getactivewindow)
Or with older versions of xdotool:
xdotool windowactivate $(xdotool search --class Chrome) &&
xdotool key F5 &&
xdotool windowactivate $(xdotool getactivewindow)
Remember that this sends F5 to that window and it's up to the program to decide what to do with it. In Chrome, this reloads the current tab.
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
).
Best Answer
If you are operating at the X level (as in Gilles' question), then use xdotool like so:
Where KEYSTROKE_SPECIFIER can be something like "a" or "F2" or "control+j"
EDIT: I missed your response to Gilles' question, sorry. I'll leave this response here as a solution for the X-case.