O Problema
Usei vários inicializadores de aplicativos como rofi
, albert
, wofi
, dmenu
, e outros ao longo dos meus anos no Linux. Embora tenham seus prós e contras, uma coisa sempre me incomodou: eles não são um shell bash.
Por que isso importa? Eu realmente gosto de alguns dos recursos do bash, como:
- Atalhos do GNU Readline: Navegar ou editar texto com
Ctrl+A
(início da linha),Ctrl+E
(fim),Ctrl+K
(matar texto),Ctrl+Y
(arrancar),Meta+Y
(arrancar histórico) e muito mais. - Histórico de comandos: Use
~/.bash_history
para pesquisar comCtrl+R
/Ctrl+S
ou navegar pelos comandos comCtrl+P
/Ctrl+N
. - Completamento de tabulação: com ferramentas como
bash-completion
ebash-complete-alias
, tenho um poderoso autocompletar para caminhos, nomes de comandos e argumentos. - Aliases: Alguns programas são mais fáceis e rápidos de iniciar por meio dos meus aliases personalizados.
Meu Objetivo
Quero usar um emulador de terminal como um simples iniciador de aplicativo. Eis como deve funcionar:
- Pressione uma tecla de atalho para iniciar o terminal (por exemplo,
kitty
). - Digite um comando (por exemplo,
firefox
). - Pressione
<Enter>
. O terminal deve:- Inicie o comando.
- Feche-se imediatamente.
- Deixe o aplicativo iniciado em execução.
Por exemplo, digitar firefox
deve se comportar como executar firefox & disown & exit
ou nohup firefox > /dev/null 2>&1 & exit
. Digitar & disown & exit
depois do comando atinge o efeito desejado, mas, é claro, não quero adicionar manualmente & disown & exit
todas as vezes.
Nota: isso não é engolir janelas . Não quero que a janela do terminal fique parada depois que o aplicativo fecha; só preciso dela para entrada.
O que eu tentei
Usando
read
:
Iniciandokitty
com este comando:kitty -e bash -i -c 'read -e -p "Command: " cmd; eval "$cmd"'
Essa abordagem falha porque digitar
read
ignora alguns dos recursos do shell que eu quero, como conclusão de tabulação e histórico de comandos.Automatizando com um atalho secundário:
Digitando o comando e usando outro atalho (por exemplo,Super+<Enter>
) para anexar e executar& disown & exit<Enter>
com uma ferramenta comowtype
.
Isso é muito trabalhoso, mas eu me contentaria com isso, se funcionasse. Infelizmente, não funciona: pressionar uma tecla modificadora comoSuper
causa um comportamento indesejado: cada caractere na string (& disown & exit<Enter>
) é enviado com o modificador, disparando atalhos em vez de ser interpretado como texto.
Conclusão
Como posso conseguir isso? Quero uma solução que me permita iniciar aplicativos rapidamente, aproveitando todos os recursos de um shell bash interativo.
Eu faria isso nesta ordem mental:
disown
ing ounohup
ing`A instalação desse hook pode ser feita em um arquivo RC personalizado que você especifica para carregar.
O gancho em si:
fácil em
zsh
(Eu realmente recomendaria
zsh
aqui), apenas implementepreexec
; coloque algo como o seguinte em seu~/.zshrc
e execute seu terminal como
kitty -e env PROMPT_AND_EXIT=1 zsh
.bash
: possível, mas um pouco mais difícil, eu achorealmente não tentei, mas tenho certeza de que você pode "remendar" um comportamento semelhante em
bash
como você obtém compreexec
onzsh
. Uma rápida olhada nobash
código-fonte de 's não mostra nada que se assemelhe aozsh
de 'spreexec()
, mas você provavelmente pode implementar umDEBUG something_invoke_exec
hook. Isso parece um pouco mais trabalhoso (e potencialmente tem desvantagens de desempenho), mas permitiria que você fizesse conceitualmente o mesmo que eu mostrei parazsh
. Não tentei isso, no entanto, por tempo limitado (e uso limitado – achobash
a edição de linha de comando de 's muito menos avançada do que a dezsh
's e, portanto, prefiro a última em uso interativo). Valeria a pena você investigar!