O zsh fornece algumas boas funções de gancho , incluindo chpwda execução de uma função depois que o usuário altera os diretórios.
Estou tentando imitar isso no bash.
Ele deve funcionar em shells interativos e não interativos, o que eu acho que significa que ele não pode confiar em algo como $PROMPT_COMMAND
Não pode redefinir cd, porque quero que funcione para qualquer comando que altere diretórios (por exemplo, pushde popd)
Ele deve ser executado após o comando do usuário, para trap "my_function" DEBUGque não funcione, a menos que eu possa de alguma forma dizer lá, "primeiro execute o $BASH_COMMANDtrapping, depois faça isso ..." Vejo que posso evitar a execução automática de $BASH_COMMAND se extdebug estiver ativado ea função trap retorna 1, mas acho que não quero forçar extdebug, e retornar 1para um comando bem-sucedido (mas modificado) parece errado.
A última parte - "execute o comando do usuário" - é o que atualmente me deixou perplexo. Se eu puder executar uma função após cada comando, posso verificar se o diretório foi alterado desde a última verificação. Por exemplo:
Estou no caminho certo ou existe uma maneira melhor? Como posso executar um comando no bash depois que o usuário altera os diretórios?
Por que não redefinir cd, pushde popd? Quantas outras maneiras existem para alterar o diretório?
— Jk013
@ jw013 este código destina-se a um projeto de código aberto no qual o mantenedor listou especificamente não redefinir cdcomo princípio.
Além disso - "quantas outras maneiras existem para alterar o diretório" - não sei, que é outra razão pela qual prefiro não confiar em listá-las explicitamente.
Por que você quer fazer isso? Sua função pode interromper muitos programas (C, Java, ..). Nos scripts que eu uso, por MYBIN=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P )favor, não altere os comandos Unix confiáveis.
@ NathanLong isso é apenas para o meu sistema operacional . O sistema operacional parece irrelevante aqui. O SO importa? É o shell que importa na sua pergunta, e você parece estar perguntando especificamente bash, o que funciona da mesma forma em todos os sistemas operacionais em que é executado.
Não há como atender a essas restrições
Parece que não há como resolver esse problema no bash com minhas restrições. Em geral, as soluções possíveis são:
Override cd, pushde popd, de modo que qualquer comando que altera diretórios irá primeiro executar a função de gancho. Mas isso pode criar problemas, porque 1) a substituição deve ser cuidadosa para concluir a tabulação como o comando original e retornar o mesmo código de saída e 2) se mais de uma ferramenta adotar essa abordagem, elas não poderão funcionar bem juntas
Substitua todos os comandos que podem ser executados com as alterações do ambiente para executar primeiro a função de gancho. Isso é difícil porque existem muitos desses comandos
trap 'my_functionDEBUG so that every command will run the hook function. This is suboptimal because 1) it runs before every command, 2) it runs *before*cd`, não depois de 3), pode haver apenas uma função de depuração; portanto, se outra ferramenta usar essa abordagem, eles não poderão tocar bem juntos
Redefina $PROMPT_COMMANDpara executar a função de gancho primeiro. Isso é subótimo porque não funcionará em shells não interativos e, se outra ferramenta definir o comando prompt, eles não poderão funcionar bem juntos.
Em resumo, parece que a única ótima solução seria se o bash fornecesse algo como o chpwd_functionsgancho do zshell , mas parece impossível simular isso adequadamente.
Se o mantenedor não gostar de alterar a definição do cd, outra opção seria redefinir todos os comandos que usam este ambiente no diretório:
Isso seria bastante eficiente porque o gancho PWD e a configuração no diretório seriam processados ​​apenas quando necessário.
No seu exemplo de função check_pwd, posso mudar:
para passar no novo cwd (pode ser mais modular, testável).
"redefina todos os comandos que usam esse ambiente no diretório" Infelizmente, não posso prever isso.
Instale as ferramentas inotify de acordo com sua distribuição.
No meu exemplo, o comando a seguir será reiniciado httpdse algo mudar (Modificar, Criar, Excluir) no diretório especificado.