No bash, posso providenciar para que uma função seja executada antes de executar um comando?
Existe $PROMPT_COMMAND
, que é executado antes de mostrar um prompt, ou seja, logo após a execução de um comando.
O Bash's $PROMPT_COMMAND
é análogo à precmd
função do zsh ; então o que estou procurando é um equivalente equivalente ao zsh preexec
.
Exemplos de aplicações: defina o título do seu terminal para o comando que está sendo executado; adicionar automaticamente time
antes de cada comando.
command-line
bash
hook
Gilles
fonte
fonte
PS0
variável que age comoPS1
mas é usada após a leitura do comando, mas antes de executá-lo. Veja gnu.org/software/bash/manual/bashref.html#Bash-VariablesRespostas:
Não nativamente, mas pode ser hackeado usando a
DEBUG
armadilha. Este código é configuradopreexec
eprecmd
funciona de forma semelhante ao zsh. A linha de comando é passada como um único argumento parapreexec
.Aqui está uma versão simplificada do código para configurar uma
precmd
função que é executada antes de executar cada comando.Esse truque é devido a Glyph Lefkowitz ; graças ao bcat por localizar o autor original.
Editar. Uma versão atualizada do hack do Glyph pode ser encontrada aqui: https://github.com/rcaloras/bash-preexec
fonte
"$BASH_COMMAND" = "$PROMPT_COMMAND"
comparação não está funcionando para mim i.imgur.com/blneCdQ.pngtime for i in {1..10}; do true; done
leva 0,040 segundos normalmente e 1,400 a 1,600 segundos após a ativação da interceptação DEBUG. Isso faz com que o comando trap seja executado duas vezes por loop - e no Cygwin a forquilha necessária para executar o sed é proibitivamente lenta em aproximadamente 0,030 segundos para forquear sozinha (diferença de velocidade entre oecho
embutido e/bin/echo
). Algo para se lembrar, talvez.PROMPT_COMMAND
variável (por exemplo delimitado por;
), você pode precisar usar correspondência de padrões na segunda linha dapreexec_invoke_exec
função, tal como este:[[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]]
. Isso ocorre porqueBASH_COMMAND
representa cada um dos comandos separadamente.Você pode usar o
trap
comando (dehelp trap
):Por exemplo, para alterar o título do terminal dinamicamente, você pode usar:
A partir desta fonte.
fonte
help trap
diz "Se um SIGNAL_SPEC for DEBUG, o ARG será executado após cada comando simples" [grifo meu].trap '[ -n "$COMP_LINE" ] && [ "$BASH_COMMAND" != "$PROMPT_COMMAND" ] && date "+%X";echo -e "\e]0;$BASH_COMMAND\007"' DEBUG
. Isso coloca o comando no título e também imprime a hora atual antes de cada comando, mas não o faz durante a execução$PROMPT_COMMAND
.[ -z "$COMP_LINE" ]
.Não é uma função shell que é executada, mas contribuí com uma
$PS0
string de prompt que é exibida antes de cada comando ser executado. Detalhes aqui: http://stromberg.dnsalias.org/~strombrg/PS0-prompt/$PS0
está incluído nobash
4.4, embora demore um tempo para a maioria dos Linux incluir o 4.4 - você pode criar o 4.4 se quiser; nesse caso, você provavelmente deve colocá-lo em baixo/usr/local
, adicioná-lo a/etc/shells
echsh
a ele. Em seguida, efetue logout e logon novamente, talvezssh
para você mesmo @ localhost ousu
para si mesmo primeiro como teste.fonte
Recentemente, tive que resolver esse problema exato para um projeto paralelo meu. Criei uma solução bastante robusta e resiliente que emula a funcionalidade preexec e precmd do zsh para o bash.
https://github.com/rcaloras/bash-preexec
Ele foi originalmente baseado na solução de Glyph Lefkowitz, mas eu a aprimorei e a atualizei. É um prazer ajudar ou adicionar um recurso, se necessário.
fonte
Obrigado pelas dicas! Acabei usando isso:
Desfrutar!
fonte
Eu escrevi um método para registrar todos os comandos / bash 'bash' em um servidor de arquivo de texto ou 'syslog' sem usar um patch ou uma ferramenta executável especial.
É muito fácil de implantar, pois é um shellscript simples que precisa ser chamado uma vez na inicialização do 'bash'.
Veja o método aqui .
fonte