Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
artur.sc
Sędziwy Jeż
Sędziwy Jeż
Posty: 63
Rejestracja: 09 kwie 2010, 14:18
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86

Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: artur.sc »

Witam,

W jaki sposób w bash można sprawdzić, czy określony klawisz na klawiaturze jest naciśnięty ?
Próbowałem za pomocą polecenia read z bardzo krótkim czasem oczekiwania:

Kod: Zaznacz cały

read -n 1 -t 0.000001 key;
Działa, jeśli się uruchomi program w konsoli. Jednak gdy stworzyłem 'aktywator programu' i jako typ wybrałem 'program' a nie 'program w konsoli' - to skrypt nie reaguje na naciśnięcia klawiszy.

Pozdrawiam,
Artur
Awatar użytkownika
azhag
Serdeczny Borsuk
Serdeczny Borsuk
Posty: 151
Rejestracja: 24 maja 2010, 19:30
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Fluxbox
Architektura: x86
Kontakt:

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: azhag »

Ja bym raczej kombinował z xev lub xkbevd (działa tylko w X!).
Polski portal Debiana: http://dug.net.pl/
artur.sc
Sędziwy Jeż
Sędziwy Jeż
Posty: 63
Rejestracja: 09 kwie 2010, 14:18
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: artur.sc »

Dzięki za odpowiedź.
xev wymaga podania id okna które będzie analizowało.
Mnie zależy na tym, aby skrypt zareagował na klawisz niezależnie od tego, jakie okno jest aktywne.
Awatar użytkownika
cukier_lukier
Przyjaciel
Przyjaciel
Posty: 1250
Rejestracja: 14 cze 2006, 18:25
Płeć: Mężczyzna
Wersja Ubuntu: 14.04
Środowisko graficzne: Brak
Architektura: x86

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: cukier_lukier »

Może coś z tego, choć podobne...:
http://www.unix.com/shell-programming-s ... tchar.html
A zwłaszcza:

Kod: Zaznacz cały

echo -n "Press key:"
stty -echo raw
c=$(dd bs=1 count=1 2>/dev/null )
stty echo -raw
echo " key:$c"
artur.sc
Sędziwy Jeż
Sędziwy Jeż
Posty: 63
Rejestracja: 09 kwie 2010, 14:18
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: artur.sc »

Kod: Zaznacz cały

echo -n "Press key:"
stty -echo raw
c=$(dd bs=1 count=1 2>/dev/null )
stty echo -raw
echo " key:$c"
To nie spełnia dwóch wymagań:
1. Skrypt zatrzyma się i będzie czekał na wprowadzenie znaku - a mnie chodzi tylko o to, aby sprawdził czy w danym momencie jest wciśnięty np. klawisz 'Q' - i w zależności od tego czy jest, czy nie, wykonywał inne funkcje.
2. Zadziała tylko wtedy, gdy skrypt będzie uruchomiony w terminalu. Gdy uruchomimy go za pomocą 'aktywatora programu' jak to opisałem powyżej - będzie ten sam problem co z read...
Awatar użytkownika
beluosus
Zakręcona Traszka
Zakręcona Traszka
Posty: 695
Rejestracja: 01 paź 2006, 15:32
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86
Kontakt:

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: beluosus »

Sprawdź plik /dev/input/by-path/*kbd
A najlepiej powiedz co chcesz osiągnąć. Opisz cel, a nie narzucone przez siebie (być może złe) kroki do osiągnięcia tego celu.
Kurs Linuksa: for i in $(ls /bin); do man $i; done
__________________
http://beluosus.pl/
artur.sc
Sędziwy Jeż
Sędziwy Jeż
Posty: 63
Rejestracja: 09 kwie 2010, 14:18
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: artur.sc »

beluosus pisze:Sprawdź plik /dev/input/by-path/*kbd
To już troche lepsze.
Minusy:
1. Aby podejrzeć wymaga uprawnień roota (istotne).
2. Nie mam pojęcia w jaki sposób to analizować - tzn. jak miałby wyglądać w skrypcie warunek na naciśnięcie klawisza 'Q'.
A najlepiej powiedz co chcesz osiągnąć. Opisz cel, a nie narzucone przez siebie (być może złe) kroki do osiągnięcia tego celu.
Skrypt ma być uruchamiany za pomocą 'aktywatora programu' jako 'program' a nie 'program w terminalu' - więc będzie działał w tle, nie będzie widać terminala.
W nieskończonej pętli ma wykonywać różne rzeczy i reagować na polecenia z klawiatury.
Np. gdy nacisnę 'Q' - ma zakończyć swoją pracę.
Awatar użytkownika
beluosus
Zakręcona Traszka
Zakręcona Traszka
Posty: 695
Rejestracja: 01 paź 2006, 15:32
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86
Kontakt:

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: beluosus »

Da radę to zrobić w bashu (uprawnienia można zmienić) ale to w sumie bezsensowne. Nie możesz do tego użyć globalnych skrótów klawiaturowych? I wcale nie opisałeś celu tylko znowu kroki z tym, że bardziej szczegółowo.
Kurs Linuksa: for i in $(ls /bin); do man $i; done
__________________
http://beluosus.pl/
artur.sc
Sędziwy Jeż
Sędziwy Jeż
Posty: 63
Rejestracja: 09 kwie 2010, 14:18
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: artur.sc »

beluosus pisze:Da radę to zrobić w bashu (uprawnienia można zmienić) ale to w sumie bezsensowne.
Uprawnienia uprawnieniami, ale pytanie jak skorzystać z tych danych z poziomu basha...
Nie możesz do tego użyć globalnych skrótów klawiaturowych?
Nie wiem jak powiązać globalny skrót klawiaturowy ze zmienną bash.
Poza tym nie do końca o to mi chodzi. Ciężko ustalić aby klawisz 'Q' - był na stałe skrótem klawiaturowym...
I wcale nie opisałeś celu tylko znowu kroki z tym, że bardziej szczegółowo.
Nie bardzo rozumiem czego oczekujesz...
Opisałem jaki skrypt chce stworzyć. To co będzie robił po naciśnięciu konkretnych klawiszy nie ma tutaj żadnego znaczenia.
artur.sc
Sędziwy Jeż
Sędziwy Jeż
Posty: 63
Rejestracja: 09 kwie 2010, 14:18
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: artur.sc »

Odświeżam temat, czy ktoś wie jak coś takiego zrobić ?
Jak można za pomocą klawiatury sterować skryptem bash działającym w pętli - gdy skrypt nie jest uruchamiany w terminalu ?
Awatar użytkownika
Dwimenor
Przebojowy Jelonek
Przebojowy Jelonek
Posty: 1260
Rejestracja: 18 mar 2008, 16:14
Płeć: Mężczyzna
Wersja Ubuntu: 13.10
Architektura: x86_64

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: Dwimenor »

Bash jest powłoką i zrobienie czegoś takiego wykracza poza zastosowanie powłoki.

Jak ktoś wspomniał powyżej: lepiej użyć skrótów klawiaturowych i przypisać poszczególne akcje do poszczególnych rzeczy, które skrypt miał wykonywać.
Napisz więcej, co konkretnie twój skrypt robi.
Poniższe zdanie jest fałszywe.
Powyższe zdanie jest prawdziwe.
artur.sc
Sędziwy Jeż
Sędziwy Jeż
Posty: 63
Rejestracja: 09 kwie 2010, 14:18
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: artur.sc »

> Bash jest powłoką i zrobienie czegoś takiego wykracza poza zastosowanie powłoki.

Hmm, no jak dla mnie to może być jakiś malutki program w C++ lub czymkolwiek innym, który po podaniu mu na wejście żądanej litery zwróci 1, gdy klawisz naciśnięty i 0, gdy klawisz nie jest naciśnięty.

Mógłby działać podobnie jak

Kod: Zaznacz cały

xdotool getmouselocation
- zwraca położenie myszki, np: x:403 y:405 screen:0

Ja chciałbym coś podobnego, co zwróci mi stan określonego klawisza.
Oczywiście na wejście trzeba byłoby podać ten klawisz.

> lepiej użyć skrótów klawiaturowych i przypisać poszczególne akcje do poszczególnych
> rzeczy, które skrypt miał wykonywać.

No właśnie nie lepiej :-)
Ja chce zrobić skrypt który będzie uruchamiany na kilkadziesiąt sekund - max kilka minut.
W tym czasie gdy będzie uruchomiony, będzie działał w nieskończonej pętli i robił różne rzeczy. Procesor oczywiście jest obciążony na max (a przynajmniej jeden rdzeń).
Chodzi o to, aby mieć możliwość sterowania tym co robi skrypt.
Np.:
- naciskam klawisz "d" - wykonuje zadanie przypisane do tej litery
- naciskam klawisz "p" - wykonuje zadanie przypisane do tej litery
- naciskam "spacje" - robi pauze w działaniu
- ...... itd.
- naciskam klawisz "q" - kończy pracę.
Chodzi o to, że do tego celu nie da się użyć skrótów klawiaturowych, gdyż nie mogę jako skrótu klawiaturowego używać spacji i pojedynczych liter ;-)
Skrypt miałby na czas działania "przejąć kontrolę" nad klawiaturą, tzn. w tym czasie gdy będzie uruchomiony, klawiatura nie będzie używana do normalnego pisania.
Czy teraz więcej już z tego rozumiecie ? :-)
Awatar użytkownika
Dwimenor
Przebojowy Jelonek
Przebojowy Jelonek
Posty: 1260
Rejestracja: 18 mar 2008, 16:14
Płeć: Mężczyzna
Wersja Ubuntu: 13.10
Architektura: x86_64

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: Dwimenor »

Jeżeli się upierasz, że musi monitorowanie stanu wciśnięcia klawisza, to zdecydowanie bash odpada.
Jeżeli nie upierasz się przy takiej architekturze, to zalecałbym przypisanie sobie po prostu pod f5 jednego zadania, pod f6 drugiego, a pod kolejne F coś do zabijania tamtych procesów. Najprościej robiąc coś w stylu

Kod: Zaznacz cały

if [ $1 = d ]; then
	polecenie_1
elif [ $1 = p ]; then
	polecenie_2
elif [ $1 = quit ]; then
	killall skrypt.sh; exit 0
fi
Pod F5: ścieżka/do/skrypt.sh d
Pod F6: ścieżka/do/skrypt.sh p
Pod F7: ścieżka/do/skrypt.sh quit

Coś w tym stylu. W zależności od tego, co dokładnie chcesz osiągnąć, implementacja będzie się różniła.
Jeżeli grę, to sobie odpuść i zacznij się uczyć pythona, pygame albo czegoś podobnego.
Jeżeli program w gui, to poczytaj o kdialog/zenity

A skoro już wspomniałeś o xdotool, to w dokumentacji nie ma nic na temat tego co szukasz?
Poniższe zdanie jest fałszywe.
Powyższe zdanie jest prawdziwe.
artur.sc
Sędziwy Jeż
Sędziwy Jeż
Posty: 63
Rejestracja: 09 kwie 2010, 14:18
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: artur.sc »

Dwimenor pisze: A skoro już wspomniałeś o xdotool, to w dokumentacji nie ma nic na temat tego co szukasz?
No właśnie xdotool tego nie potrafi zrobić. Da się za jego pomocą wysłać dowolny znak z klawiatury, natomiast nie jest w stanie sprawdzić czy określony klawisz jest naciśnięty.
Dziwi mnie to i zastanawia, że tak trudno znaleźć narzędzie które zrobi taką prostą rzecz...
Awatar użytkownika
Dwimenor
Przebojowy Jelonek
Przebojowy Jelonek
Posty: 1260
Rejestracja: 18 mar 2008, 16:14
Płeć: Mężczyzna
Wersja Ubuntu: 13.10
Architektura: x86_64

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: Dwimenor »

artur.sc pisze:No właśnie xdotool tego nie potrafi zrobić. Da się za jego pomocą wysłać dowolny znak z klawiatury, natomiast nie jest w stanie sprawdzić czy określony klawisz jest naciśnięty.
Dziwi mnie to i zastanawia, że tak trudno znaleźć narzędzie które zrobi taką prostą rzecz...
To jest prosta rzecz, ale nie w bashu. Np w python+pygame wygląda to mniej więcej tak (jakiś stary przykład pisany na podstawie tutoriala do pygame):

Kod: Zaznacz cały

#!/usr/bin/python 
#-*- coding: utf-8 -*-
import pygame, sys,os
from pygame.locals import * 
 
pygame.init() 
window = pygame.display.set_mode((640, 480))
pygame.display.set_caption('Monkey Fever') 
screen = pygame.display.get_surface() 

monkey_head_file_name = ("ape.bmp")

monkey_surface = pygame.image.load(monkey_head_file_name)
def pozycja_x(a):
	return a+60
def pozycja_y(b):
	return b+60

x=0
y=0
screen.blit(monkey_surface, (x, y))
pygame.display.flip() 

def zdarzenia(events): 
	for event in events: 
		if event.type == QUIT:
			sys.exit(0)
		elif event.type == KEYDOWN and event.key == K_SPACE:
			global x, y
			x = pozycja_x(x)
			y = pozycja_y(y)

			screen.blit(monkey_surface, (x,y)) 
			pygame.display.flip() 
		else:
			pass
 
while True: 
	zdarzenia(pygame.event.get())
Bash to powłoka systemowa i nie służy do rzeczy które opisałeś. Jeżeli upierasz się przy bashu to musisz zmienić architekturę programu. Jeżeli upierasz się przy swojej architekturze, to zmień język albo poproś kogoś kto ci to napiszę. Od razu mówię: nie podejmuję się tego.
Poniższe zdanie jest fałszywe.
Powyższe zdanie jest prawdziwe.
artur.sc
Sędziwy Jeż
Sędziwy Jeż
Posty: 63
Rejestracja: 09 kwie 2010, 14:18
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: artur.sc »

>To jest prosta rzecz, ale nie w bashu. Np w python+pygame wygląda to mniej więcej tak
> (jakiś stary przykład pisany na podstawie tutoriala do pygame):
> ......
Po zainstalowaniu pygame i uruchomieniu tego skryptu pojawia się nowe okno w którym cośtam się dzieje po naciśnięciu spacji. Jednak reakcja na naciśnięcie spacji jest tylko wtedy, gdy aktywne jest właśnie to okienko - mnie nie o to chodzi.


> Bash to powłoka systemowa i nie służy do rzeczy które opisałeś. Jeżeli upierasz się przy
> bashu to musisz zmienić architekturę programu. Jeżeli upierasz się przy swojej
> architekturze, to zmień język albo poproś kogoś kto ci to napiszę. Od razu mówię: nie
> podejmuję się tego.
Ja nie upieram się, że to musi być napisane w bashu. Ja w bashu chcę tylko wykorzystać wynik działania tego programu. Podobnie jak wykorzystuję w bashu

Kod: Zaznacz cały

xdotool getmouselocation
chciałbym wykorzystać program

Kod: Zaznacz cały

iskeypressed d 
do uzyskania i wykorzystania w bashu informacji o tym czy naciśnięty jest klawisz 'd'.
rack

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: rack »

No niestety, zawsze któreś z okien jest aktywne. Z jakiegoś okienka lub konsoli uruchamiasz program (pomijam te uruchamiane przy starcie) .

Pokombinuj sobie np. zenity. Ten program wyświetla sporo przydatnych okienek w zależności od parametrów. Może na coś ci się przyda.


pozdrawiam
artur.sc
Sędziwy Jeż
Sędziwy Jeż
Posty: 63
Rejestracja: 09 kwie 2010, 14:18
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: GNOME
Architektura: x86

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: artur.sc »

> No niestety, zawsze któreś z okien jest aktywne. Z jakiegoś okienka lub konsoli
> uruchamiasz program (pomijam te uruchamiane przy starcie) .

Ja wiem że zawsze któreś z okienek jest aktywne. Dlatego nie chce korzystać z takich metod jak powyższa. Chodzi raczej o program który potrafiłby analizować
/dev/input/by-path/*kbd ( o tym pisał wcześniej beluosus )
i stamtąd wyciągnąć informację o określonym klawiszu.

> Pokombinuj sobie np. zenity. Ten program wyświetla sporo przydatnych okienek w
> zależności od parametrów. Może na coś ci się przyda.
To nie o to chodzi, nie chce żadnych okienek. Chce informacje czy "d" jest naciśnięte :-)
Pozdrawiam
Awatar użytkownika
Dwimenor
Przebojowy Jelonek
Przebojowy Jelonek
Posty: 1260
Rejestracja: 18 mar 2008, 16:14
Płeć: Mężczyzna
Wersja Ubuntu: 13.10
Architektura: x86_64

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: Dwimenor »

Może zdradzisz nam dokładnie co to za projekt i dlaczego wymaga sprawdzania czy d jest wciśnięte czy nie i dlaczego rozwiązanie z klawiszami funkcyjnymi, które zaproponowałem ci nie pasuje.
Poniższe zdanie jest fałszywe.
Powyższe zdanie jest prawdziwe.
rack

Odp: Bash - sprawdzanie, czy określony klawisz jest naciśnięty.

Post autor: rack »

Stary, a odpowiedziałeś sobie gdzie ty chcesz sprawdzać, który klawisz został wciśnięty?

Wiesz, który proces chcesz śledzić, które stdin sprawdzać ???
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 15 gości