Jak wstrzykiwać naciśnięcia klawiszy za pomocą skryptu powłoki?

27

Próbuję wstrzyknąć naciśnięcia klawiszy do demona wejściowego, aby symulować pisanie ze skryptu Bash. Czy to możliwe, a jeśli tak, to jak mogę to zrobić?

Naftuli Kay
źródło
Czy chcesz symulować dane wejściowe na poziomie jądra (jeśli tak, na jakim systemie operacyjnym), na poziomie X, w terminalu?
Gilles 'SO - przestań być zły'
Na poziomie jądra chciałbym, aby wyglądało to tak, jakbym nacisnął właściwy klawisz na rzeczywistej klawiaturze.
Naftuli Kay
@TKKocheran: A więc pod AIX? FreeBSD? Linux? OSX? … Prawdopodobnie odpowiedź będzie zupełnie inna dla każdego wariantu.
Gilles „SO- przestań być zły”
1
Po co ci to?
starblue
2
Być może chciałbym napisać skrypt, który losowo wstawia naciśnięcia klawiszy w losowych odstępach czasu.
Naftuli Kay

Odpowiedzi:

23

Jeśli działasz na poziomie X (jak w pytaniu Gillesa), użyj xdotool w następujący sposób:

xdotool key KEYSTROKE_SPECIFIER

Gdzie KEYSTROKE_SPECIFIER może być czymś w rodzaju „a”, „F2” lub „control + j”

EDYCJA: Przepraszam, przegapiłem twoją odpowiedź na pytanie Gillesa. Pozostawię tę odpowiedź tutaj jako rozwiązanie dla przypadku X.

Niepewny
źródło
3
Myślę, że xtedziała na tym samym poziomie.
Cascabel
24

Użyj uinputsterownika. Nie sądzę, żeby istniało na to narzędzie; będziesz musiał napisać lub dostosować trochę kodu C. W skrócie:

#include <fcntl.h>
#include <ioctl.h>
#include <unistd.h>
#include <linux/input.h>
#include <linux/uinput.h>
/* Set up a fake keyboard device */
fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); // or /dev/input/uinput
ioctl(fd, UI_SET_EVBIT, EV_KEY);
struct uinput_user_dev uidev = …;
write(fd, &uidev, sizeof(uidev));
ioctl(fd, UI_DEV_CREATE);
/* Send an event */
struct input_event ev = …;
write(fd, &ev, sizeof(ev));
/* Clean up */
ioctl(fd, UI_DEV_DESTROY);
close(fd);

Pełniejsze referencje:

Gilles „SO- przestań być zły”
źródło
Link do einfochips.com został uszkodzony. Zamieniłem go na migawkę z archive.org.
phunehehe
czy uważasz, że to może pomóc w rozwiązaniu tego pytania? unix.stackexchange.com/questions/156985 /... Myślałem, że kiedy naciskam klawisz, ten program wyśle ​​kolejny klucz, który rozpoznaje problematyczna aplikacja (nawet jeśli w tym samym czasie)?
Aquarius Power
Przykładowy kod Thiemonge do tworzenia myszy i poruszania się po nich działa, ale nie jest w stanie dowiedzieć się, jak z niego korzystać, nawet jeśli podobno tego uczy.
Cestarian
@Cestarian To brzmi jak pytanie o przepełnienie stosu . Opublikuj swój kod, wyjaśnij, czego się spodziewałeś i co widzisz, oraz podaj odpowiednie komunikaty o błędach, wpisy do dziennika itp.
Gilles „SO - przestań być zły”
@Gilles dobrze, bardzo bym chciał, ale mówi, że osiągnąłem limit pytań ... Za otrzymanie zbyt wielu głosów negatywnych na 2 pytania, które zadałem jakiś czas temu; i prawdopodobnie trochę więcej na wiele starszych pytań, które usunąłem. Do diabła, nawet nie wiem, dlaczego mam tutaj tak wiele głosów negatywnych stackoverflow.com/questions/20619023/... (chociaż mam całkiem dobrą odpowiedź), czy to dlatego, że nie opublikowałem błędu, który otrzymałem? W każdym razie poza tematem. Zasadniczo chciałbym, ale nie mogę. :(
Cestarian
9

Jeśli NIE pracujesz z programami X z oknami, do których można wysyłać klucze, prawdopodobnie szukasz expectprzydatnego i bardzo konfigurowalnego programu do uruchamiania innych interaktywnych programów powłoki, tak jakby użytkownik kontrolował terminal. Możesz skonfigurować programowe odpowiedzi, aby reagować na różne dane wyjściowe przy użyciu różnych danych wejściowych.

Caleb
źródło
7

Napisałem kod, który to robi. Możesz go znaleźć w moim projekcie open source.

http://code.google.com/p/pycopia/source/browse/trunk/core/pycopia/OS/Linux/event.py

Jeśli uruchomisz ten moduł jako skrypt jako root, zobaczysz demo w akcji.

Ta podstawowa funkcjonalność została rozszerzona o kolejny projekt, powerdroid, który zapewnia bardziej konkretną implementację systemu wbudowanego (Android).

http://code.google.com/p/powerdroid/source/browse/trunk/src/droid/devices.py

Keith
źródło