web-dev-qa-db-fra.com

Dans bash, comment lier une clé de fonction à une commande?

Exemple: je veux lier le F12 clé de la commande echo "foobar" tel que chaque fois que je frappe F12 le message "foobar" sera imprimé à l'écran. Idéalement, cela pourrait être n'importe quelle commande Shell arbitraire, pas seulement des commandes intégrées. Comment on s'y prend?

84
SiegeX

Vous pouvez déterminer la séquence de caractères émise par une touche en appuyant sur Ctrl-v en ligne de commande, puis en appuyant sur la touche qui vous intéresse. Sur mon système, F12, Je reçois ^[[24~. Le ^[ représente Esc. Différents types de terminaux ou émulateurs de terminaux peuvent émettre des codes différents pour la même clé.

À l'invite de commandes, vous pouvez entrer une commande comme celle-ci pour activer la macro de clé afin de pouvoir l'essayer.

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

Maintenant, quand vous appuyez sur F12, vous obtiendrez "foobar" sur la ligne de commande, prêt à être édité. Si vous voulez qu'une frappe soit entrée immédiatement dans une commande, vous pouvez ajouter une nouvelle ligne:

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

Maintenant, quand vous appuyez sur F12, vous obtiendrez le répertoire actuel affiché sans avoir à appuyer sur Enter. Et si vous avez déjà tapé quelque chose sur la ligne et que vous utilisez ceci qui s'exécute automatiquement? Cela pourrait devenir compliqué. Toutefois, vous pouvez effacer la ligne dans le cadre de votre macro:

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

L’espace fait en sorte que le Ctrl-u a quelque chose à supprimer pour empêcher la cloche de sonner.

Une fois que la macro fonctionne comme vous le souhaitez, vous pouvez la rendre persistante en l'ajoutant à votre ~/.inputrc fichier. La commande bind ou l'ensemble extérieur de guillemets simples ne sont pas nécessaires:

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

Edit:

Vous pouvez également créer une liaison de clé qui exécutera quelque chose sans perturber la ligne de commande actuelle.

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

Lorsque vous tapez une commande nécessitant un nom d'utilisateur, par exemple, et que vous devez connaître le nom de l'utilisateur connecté, vous pouvez appuyer sur Alt-Shift-W et le résultat de who sera affiché et l'invite sera réémise avec votre commande partielle intacte et le curseur à la même position sur la ligne.

Malheureusement, cela ne fonctionne pas correctement pour des clés telles que F12 qui produit plus de deux caractères. Dans certains cas, cela peut être contourné.

La commande (who dans ce cas) peut être n’importe quel exécutable - un programme, un script ou une fonction.

145
Dennis Williamson

Vous pouvez définir des liaisons de clé bash dans la bibliothèque .inputrc (fichier de configuration pour la GNU Readline)). La syntaxe est la suivante:

<clé ou nom de clé>: macro

par exemple:

Control-o: "> output"

créera une macro qui insère "> sortie" lorsque vous appuyez sur ControlO

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

créera une macro qui insère "echo foobar" lorsque vous appuyez sur F1... Je ne sais pas ce que le keysym pour F11 est hors de portée.

Modifier:

.inputrc comprend le \n séquence d'échappement pour le saut de ligne, vous pouvez donc utiliser

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

Ce qui "pressera effectivement" après que la commande aura été émise.

17
Barton Chittenden

Cette solution est spécifique aux environnements X11 et n’a rien à voir avec bash, mais ajoute ce qui suit à vos .Xmodmaps

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

enverra la chaîne "foobar" au terminal après avoir frappé F12.

7
Wesley Rice

Je voulais lier Ctrl+B à une commande. Inspiré par la réponse ci-dessus, j’ai essayé d’utiliser bind mais je n’ai pas pu comprendre quelle série de gribouillis cryptiques (\e[24~ ?) traduire en Ctrl+B.

Sur un Mac, accédez à Paramètres de l'application Terminal, Profils -> Clavier -> + puis appuyez sur le raccourci clavier recherché et il sort. Pour moi Ctrl+B a abouti à \002 que j'ai lié avec succès à la commande

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

De plus, si vous souhaitez que la commande soit exécutée immédiatement (pas seulement insérée dans l'invite), vous pouvez ajouter la touche Entrée à la fin de votre commande, comme suit:

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

2
Peter Perháč