Jak w bash powiązać klawisz funkcyjny z poleceniem?

91

Przykład: Chcę przypisać F12klawisz do polecenia echo "foobar"tak, że za każdym razem, F12gdy trafię, na ekranie zostanie wyświetlony komunikat „foobar”. W idealnym przypadku mogłoby to być dowolne polecenie powłoki, a nie tylko polecenia wbudowane. Jak się do tego zabrać?

SiegeX
źródło

Odpowiedzi:

165

Możesz określić sekwencję znaków emitowaną przez klawisz, naciskając Ctrl- vw wierszu poleceń, a następnie naciskając klawisz, który Cię interesuje. W moim systemie dla F12, otrzymuję ^[[24~. ^[Reprezentuje Esc. Różne typy terminali lub emulatorów terminali mogą emitować różne kody dla tego samego klucza.

W wierszu polecenia Bash możesz wprowadzić takie polecenie, aby włączyć makro kluczowe, abyś mógł je wypróbować.

bind '"\e[24~":"foobar"'

Teraz, po naciśnięciu F12, w wierszu poleceń pojawi się „foobar”, gotowy do dalszej edycji. Jeśli chcesz, aby naciśnięcie klawisza natychmiast wprowadziło polecenie, możesz dodać nową linię:

bind '"\e[24~":"pwd\n"'

Teraz po naciśnięciu F12wyświetli się bieżący katalog bez konieczności naciskania Enter. A co, jeśli już wpisałeś coś w linii i używasz tego, co wykonuje się automatycznie? Może się zabrudzić. Możesz jednak wyczyścić linię jako część makra:

bind '"\e[24~":"\C-k \C-upwd\n"'

Przestrzeń zapewnia, że Ctrl- uma coś do usunięcia, aby dzwonek nie dzwonił.

Gdy już sprawisz, że makro będzie działało tak, jak chcesz, możesz je utrwalić, dodając je do ~/.inputrcpliku. Nie ma potrzeby używania bindpolecenia ani zewnętrznego zestawu pojedynczych cudzysłowów:

"\e[24~":"\C-k \C-upwd\n"

Edytować:

Możesz także utworzyć powiązanie klawiszowe, które wykona coś bez zakłócania bieżącego wiersza poleceń.

bind -x '"\eW":"who"'

Następnie, gdy wpisujesz polecenie, które wymaga na przykład nazwy użytkownika i musisz znać nazwy zalogowanych użytkowników, możesz nacisnąć Alt- Shift-, Wa wynik whozostanie wyświetlony, a monit zostanie ponownie wyświetlony z nienaruszonym poleceniem częściowym i kursorem w tej samej pozycji w linii.

Niestety, nie działa to poprawnie w przypadku kluczy, takich jak te, F12które wyświetlają więcej niż dwa znaki. W niektórych przypadkach można to obejść.

Polecenie ( whow tym przypadku) może być dowolnym plikiem wykonywalnym - programem, skryptem lub funkcją.

Wstrzymano do odwołania.
źródło
2
A jeśli chcę dodać powiązanie do „ctrl + q”?
kubudi
5
@kubudi: bind '"\C-q": menu-complete'na przykład (lub w ~/.inputrc: "\C-q": menu-complete). Może być również konieczne stty -ixonw twojej ~/.bashrcAby wyłączyć kontrolę przepływu i upewnij ^ S i ^ Q dostępne.
Wstrzymano do odwołania.
Mówisz, że to ^[reprezentuje, esca potem wydajesz się zastępować to \ew swoim przykładzie. Czy mógłbyś wyjaśnić, dlaczego, proszę?
Remover
1
@Remover: ^[jest reprezentacją wyjściową. Jest \eto jedyny sposób, aby go wprowadzić ( ^[nie działa).
Wstrzymano do odwołania.
Jak mogę powiązać "\ Cz"? Chciałbym dostać coś podobnego do tego, co opisano dla zsh na sheerun.net/2014/03/21/how-to-boost-your-vim-productivity
pkoch
19

Możesz zdefiniować skróty klawiszowe bash w ~/.inputrc(plik konfiguracyjny biblioteki GNU Readline). Składnia to

<keysym lub nazwa klucza>: makro

na przykład:

Control-o: "> output"

stworzy makro, które po naciśnięciu wstawi "> wyjście" ControlO

 "\e[11~": "echo foobar"

stworzy makro, które wstawi "echo foobar" po naciśnięciu F1... Nie wiem, do czego klawisze F11są od ręki.

Edytować:

.inputrcrozumie \nsekwencję ucieczki dla wysuwu wiersza, więc możesz użyć

 "\e[11~": "echo foobar\n"

Który skutecznie `` naciśnie enter '' po wydaniu polecenia.

Barton Chittenden
źródło
4
możesz użyć „\ n” w makrze, aby dodać znak nowego wiersza:
Barton Chittenden,
Działa to lepiej dla mnie, ponieważ definiuje mapowanie klawiszy podczas otwierania terminala.
Heldraug,
Do Altużytku \enp "\eo": "> output".
Jānis Elmeris
Aby uzyskać bardziej szczegółowy samouczek na temat używania, .inputrczobacz hackaday.com/2018/01/19/linux-fu-custom-bash-command-completion
Josh Habdas
1
@ArthurHenriqueDellaFraga Poprawiłem odpowiedź; będzie w twoim katalogu domowym. Jeśli nie istnieje, możesz go utworzyć.
Barton Chittenden
7

To rozwiązanie jest specyficzne dla środowisk X11 i nie ma nic wspólnego z bash, ale dodaje następujące elementy do twoich .Xmodmaps

 % loadkeys
 keycode 88 = F12
 string F12 = "foobar"
 %

wyśle ​​napis „foobar” do terminala po naciśnięciu F12.

Wesley Rice
źródło
Należy pamiętać, że to nie to samo, co powłoka wykonująca polecenie. Jeśli faktycznie chcesz uruchomić polecenie, musisz nacisnąć klawisz Enter (lub poprosić o wysłanie ciągu znaków). Prawdopodobnie też chcesz być bezpieczny i najpierw pokonać linię.
Cascabel
2
Byłoby to niesamowite, ale i tak nie wydaje się działać w Fedorze 20. Próbowałem nawet najpierw użyć xev, aby znaleźć właściwy kod klucza dla F12 (w moim przypadku 96) i użyć go zamiast 88. Żaden z nich nie działa.
BobDoolittle,
2

Chciałem związać Ctrl+Bsię z poleceniem. Zainspirowany powyższą odpowiedzią, próbowałem użyć, bindale nie mogłem dowiedzieć się, na jaką serię tajemniczych zawijasów ( \e[24~?) Tłumaczy się Ctrl+B.

Na komputerze Mac przejdź do Ustawienia aplikacji Terminal, Profile -> Klawiatura -> +następnie naciśnij skrót klawiaturowy, którego szukasz, i pojawi się. Dla mnie Ctrl+Bzaowocowało to \002sukcesem w dowodzeniu

bind '"\002":"echo command"'

Ponadto, jeśli chcesz, aby polecenie zostało wykonane od razu (a nie tylko wstawione do monitu), możesz dodać Enter na końcu polecenia, na przykład:

bind '"\002":"echo command\015"'

Peter Perháč
źródło