No bash, como vinculo uma tecla de função a um comando?

91

Exemplo: Quero vincular a F12tecla ao comando de echo "foobar"forma que toda vez que eu acionar F12a mensagem "foobar" seja impressa na tela. Idealmente, poderia ser qualquer comando de shell arbitrário, não apenas builtins. Como fazer isso?

SiegeX
fonte

Respostas:

163

Você pode determinar a sequência de caracteres emitida por uma tecla pressionando Ctrl- vna linha de comando e, em seguida, pressionando a tecla na qual está interessado. No meu sistema F12, eu entendo ^[[24~. O ^[representa Esc. Diferentes tipos de terminais ou emuladores de terminal podem emitir códigos diferentes para a mesma chave.

Em um prompt do Bash, você pode inserir um comando como este para habilitar a macro chave para que você possa experimentá-la.

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

Agora, quando você pressiona F12, você obterá "foobar" na linha de comando pronto para edição posterior. Se você deseja que um pressionamento de tecla insira um comando imediatamente, você pode adicionar uma nova linha:

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

Agora, quando você pressiona F12, o diretório atual é exibido sem ter que pressionar Enter. E se você já tiver digitado algo na linha e usar isso, que é executado automaticamente? Pode ficar confuso. No entanto, você pode limpar a linha como parte de sua macro:

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

O espaço garante que Ctrl- utenha algo a excluir para evitar que a campainha toque.

Depois de fazer a macro funcionar da maneira que você deseja, pode torná-la persistente adicionando-a ao seu ~/.inputrcarquivo. Não há necessidade do bindcomando ou do conjunto externo de aspas simples:

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

Editar:

Você também pode criar uma combinação de teclas que executará algo sem perturbar a linha de comando atual.

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

Então, enquanto você está digitando um comando que requer um nome de usuário, por exemplo, e você precisa saber os nomes dos usuários que estão logados, você pode pressionar Alt- Shift- We a saída de whoserá exibida e o prompt será reemitido com seu comando parcial intacto e o cursor na mesma posição na linha.

Infelizmente, isso não funciona corretamente para teclas como as F12que geram mais de dois caracteres. Em alguns casos, isso pode ser contornado.

O comando ( whoneste caso) pode ser qualquer executável - um programa, script ou função.

Pausado até novo aviso.
fonte
2
E se eu quiser adicionar um vínculo a "ctrl + q"?
kubudi
5
@kubudi: bind '"\C-q": menu-complete'por exemplo (ou na sua ~/.inputrc: "\C-q": menu-complete). Você também pode precisar stty -ixonem sua ~/.bashrcpara controle de fluxo de desativar e fazer ^ S e ^ Q disponível.
Pausado até novo aviso.
Você diz que ^[representa esce então parece substituí-lo \eem seu exemplo. Você poderia explicar por que, por favor?
Removedor
1
@Remover: ^[é a representação de saída. Essa \eé uma maneira de entrar ( ^[não funciona para isso).
Pausado até novo aviso.
Como posso vincular "\ Cz"? Adoraria obter algo como o que está descrito para zsh em sheerun.net/2014/03/21/how-to-boost-your-vim-productivity
pkoch
19

Você pode definir combinações de teclas bash em ~/.inputrc(arquivo de configuração para a biblioteca GNU Readline). A sintaxe é

<keysym ou key name>: macro

por exemplo:

Control-o: "> output"

irá criar uma macro que insere "> saída" quando você pressiona ControlO

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

irá criar uma macro que insere "echo foobar" quando você pressiona F1... Não sei para que F11serve o keysym .

Editar:

.inputrcentende a \nsequência de escape para alimentação de linha, então você pode usar

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

Que irá efetivamente 'pressionar enter' após o comando ser emitido.

Barton Chittenden
fonte
4
você pode usar "\ n" dentro de uma macro, para adicionar um caractere de nova linha:
Barton Chittenden
Isso funciona melhor para mim, pois define o mapeamento de teclas ao abrir um terminal.
Heldraug de
Para Alt, use \e, por exemplo "\eo": "> output".
Jānis Elmeris
Para um tutorial mais aprofundado sobre como usar .inputrc consulte hackaday.com/2018/01/19/linux-fu-custom-bash-command-completion
Josh Habdas
1
@ArthurHenriqueDellaFraga editei a resposta; ele estará em seu diretório inicial. Se não existir, você pode criá-lo.
Barton Chittenden
7

Esta solução é específica para ambientes X11 e não tem nada a ver com bash, mas adicionar o seguinte ao seu .Xmodmaps

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

irá enviar a string "foobar" para o terminal ao pressionar F12.

Arroz wesley
fonte
Lembre-se de que não é o mesmo que o shell que executa um comando. Se você realmente deseja executar um comando, terá que pressionar enter (ou mandar a string enviada fazer isso para você). Provavelmente também deseja estar seguro e limpar a linha primeiro.
Cascabel
2
Isso seria incrível, mas não parece funcionar no Fedora 20 de qualquer maneira. Até tentei usar o xev para encontrar primeiro o código-chave adequado para F12 (no meu caso, 96) e usá-lo em vez de 88. Nenhum dos dois funciona.
BobDoolittle
2

Eu queria me vincular Ctrl+Ba um comando. Inspirado por uma resposta acima, tentei usar, bindmas não consegui descobrir que série de rabiscos enigmáticos (\e[24~ ?) Se traduziam Ctrl+B.

Em um Mac, vá para Configurações do aplicativo Terminal, Perfis -> Teclado ->, em +seguida, pressione o atalho de teclado que você está procurando e ele aparecerá. Para mim Ctrl+Bresultou em \002que eu vinculei com sucesso ao comando

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

Além disso, se você deseja que o comando seja executado imediatamente (não apenas inserido no prompt), você pode adicionar o Enter ao final do seu comando, assim:

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

Peter Perháč
fonte