Simulate keystroke in Linux with Python
Asked Answered
B

6

22

How can I simulate a keystroke in python? I also want to press multiple keys simultaneously.

Something like:

keystroke('CTRL+F4')

or

keystroke('Shift+A')
Behring answered 19/4, 2011 at 9:11 Comment(1)
May I ask why you want to do this? Also, under which environment? Command line? Graphical Desktop?Aplacental
M
15

Although it's specific to X, you can install the xautomation package (apt-get install xautomation on Debian-based systems) and use xte to simulate keypresses, e.g.:

from subprocess import Popen, PIPE

control_f4_sequence = '''keydown Control_L
key F4
keyup Control_L
'''

shift_a_sequence = '''keydown Shift_L
key A
keyup Shift_L
'''

def keypress(sequence):
    p = Popen(['xte'], stdin=PIPE)
    p.communicate(input=sequence)

keypress(shift_a_sequence)
keypress(control_f4_sequence)
Marja answered 19/4, 2011 at 9:29 Comment(1)
How can I send keys to the shell?Lenten
S
19

Consider python-uinput and evdev. Example of shift+a with the latter:

from evdev import uinput, ecodes as e

with uinput.UInput() as ui:
    ui.write(e.EV_KEY, e.KEY_LEFTSHIFT, 1)
    ui.write(e.EV_KEY, e.KEY_A, 1)
    ui.syn()
Seneschal answered 23/8, 2012 at 17:5 Comment(6)
I tried similar code, it is exeuted because I see in system log that a new virtual input device was created but the keystrokes do not appear in X? Any special thing can be done so the keys are received by X server?Grimonia
The links are deadSaddle
This is great! Note that 1 is a keydown event and 0 is keyup, so if you wanted to simulate a pressing and releasing a key more than once, you would need to place something like the following lines in a loop: ui.write(ecodes.EV_KEY, ecodes.KEY_DOWN, 1) #key down ui.write(ecodes.EV_KEY, ecodes.KEY_DOWN, 0) #key up ui.syn()Prior
it gave me this error: UInputError: "/dev/uinput" cannot be opened for writing Any suggestion?Schopenhauerism
Adding KERNEL=="uinput", MODE="0666 to the top of /etc/udev/rules.d/50-rogdrv.rules and reloading rules solves the problem" (github issue) You can reload udev rules like this # udevadm control --reload-rules && udevadm trigger (source)Cornerstone
The example given only requires evdev. After I did pip install evdev, I pasted the example into a python3 interpreter. It worked straight away. It may have helped that I already had the uinput kernel module loaded.- modprobe uinput.Yoshikoyoshio
R
15

python-uinput:

Pythonic API to Linux uinput kernel module...

Python-uinput is Python interface to Linux uinput kernel module which allows attaching userspace device drivers into kernel. In practice, Python-uinput makes it dead simple to create virtual joysticks, keyboards and mice for generating arbitrary input events programmatically...

Riggins answered 19/4, 2011 at 9:12 Comment(2)
Can i emit in lowercase? please an example!!Congruous
the link is deadSaddle
M
15

Although it's specific to X, you can install the xautomation package (apt-get install xautomation on Debian-based systems) and use xte to simulate keypresses, e.g.:

from subprocess import Popen, PIPE

control_f4_sequence = '''keydown Control_L
key F4
keyup Control_L
'''

shift_a_sequence = '''keydown Shift_L
key A
keyup Shift_L
'''

def keypress(sequence):
    p = Popen(['xte'], stdin=PIPE)
    p.communicate(input=sequence)

keypress(shift_a_sequence)
keypress(control_f4_sequence)
Marja answered 19/4, 2011 at 9:29 Comment(1)
How can I send keys to the shell?Lenten
R
4

If you plan to use it on Linux, try pyautogui library. For multiple keys you will need to use hotkey, e.g.:

pyautogui.hotkey('ctrl', 'c')  # ctrl-c to copy

For me it worked - see here: How to pass a keystroke (ALT+TAB) using Popen.communicate (on Linux)?

Relume answered 26/1, 2018 at 14:40 Comment(1)
Works on windows as well.Oldster
O
2

If you are on Windows, use Sendkeys and if on Linux, try out the suggestion given here for xsendkeys or pexpect.

Olive answered 19/4, 2011 at 9:15 Comment(0)
V
2

Simplest solution I have found was using pynput. You could do the following:

from pynput.keyboard import Key, Controller

keyboard = Controller()
with keyboard.pressed(Key.ctrl):
   keyboard.press(Key.f4)
   keyboard.release(Key.f4)
Visigoth answered 6/10, 2020 at 21:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.