Como ele substitui meu histórico quando usado em vários terminais, desejo desativar a funcionalidade fc -W
. Infelizmente, tenho o hábito de digitá-lo com frequência.
Acho que não é possível fazer um alias, pois há um espaço em branco no arquivo fc -W
.
Então eu tentei fazer uma função, algo assim:
# Make sure to never invoke fc -W
fc(){
for x; do
if [[ "${x}" == -W ]]; then
echo "I'm sorry Dave. I'm afraid I can't do that."
return
fi
done
fc "${@}"
}
No entanto, agora a chamada fc "${@}"
chama a si mesma e obtenho recursão infinita. Normalmente, eu evitaria isso usando, por exemplo /usr/bin/fc
, em vez de fc
, no entanto:
$ type fc
> fc is a shell builtin
Como posso evitar a recursão infinita neste caso? Ou existe uma maneira melhor de desabilitar um sinalizador de um comando?
Usar
builtin
:Isso garantirá que o
fc
comando integrado seja chamado.Estilo: a mensagem de diagnóstico deve ir para o fluxo de erro padrão e a função deve retornar um status diferente de zero ao falhar:
Você pode substituir um comando interno ou um comando externo ou uma função com um alias. Enquanto o alias estiver em execução, um alias com o mesmo nome não será expandido. Assim, se a expansão do alias usar o nome do alias, isso chamará o comando interno ou externo ou a função de mesmo nome. Isso significa que você pode usar um alias de maneira simples para passar opções extras para um comando. Mas você não pode fazer muito mais, devido ao modo como a expansão de alias funciona — é uma simples substituição de palavras, sem avaliação.
Você pode substituir um comando interno ou um comando externo por uma função. O fato de uma função com um determinado nome estar em execução não afeta a execução e, em particular, não afeta o significado do nome da função: ele continua se referindo à função. As funções recursivas não são comuns na programação shell, mas não há nenhuma regra contra elas.
Em shells POSIX, você pode forçar um nome a se referir a um comando interno ou externo colocando
command
antes da chamada. Em outras palavras,command
ignora aliases e funções. No zsh,command
força uma chamada para um comando externo (a menos que a opçãoposix_builtins
esteja definida), ou seja, também ignora os builtins. Para forçar a execução de um builtin no zsh, use obuiltin
método builtin.Isso leva a uma solução: em sua função wrapper, chame
builtin fc
em vez defc
.No entanto, esta não é necessariamente a melhor solução no seu caso, porque sua função será invocada em todos os lugares, incluindo chamadas
fc
de outras funções. Quando você substitui o comportamento integrado, recomendo usar um alias. Um alias só se aplica ao que você digita na linha de comando ou carrega com.
(também conhecido comosource
), não para funções carregadasautoload -U
(que é a maneira recomendada de carregar automaticamente uma função). Portanto, defina umfc
alias que chame sua função wrapper e dê um nome diferente à sua função wrapper.Eu coloquei
\fc
em vez defc
na definição da função. Isso não é necessário ao carregar a definição.zshrc
antes da definição do alias, mas é necessário, por exemplo, se você editar ou recarregar a definição da função durante sua sessão interativa. Também fiz algumas pequenas melhorias na função:fc -WI
. Isso não é totalmente robusto, pois também captura uma chamada comofc -R -- -W
(lendo o histórico de um arquivo chamado-W
), mas é bom o suficiente para este caso de uso.