Localizando a origem de uma função em zsh

Localizando a origem de uma função em zsh

Eu tenho esse problema irritante em meu shell zsh, onde uma função está sendo declarada em algum lugar e essa função é chamada de "cp", portanto, está substituindo o comportamento normal do cp. Estou tentando localizar a declaração da função, mas não consigo. Já procurei nos locais normais do .zshrc e nas diversas outras fontes que estão sendo incluídas no .zshrc mas até agora nada.

Outras coisas que tentei:

  • grep -r 'function cp' .(de ~)
  • whence -f cp(fornece a definição da função, mas não de onde ela foi declarada)

Alguma ideia?

Responder1

Primeiro de tudo, uma função pode ser definida sem a functionpalavra-chave, portanto uma pesquisa melhor seria

grep 'cp()' .*

Isso pesquisará arquivos como .zshrce .profilee outros enfeites. Se não encontrar nada, você também pode querer ver os vários arquivos carregados por zsh. Eles estão listados no final de man zsh:

FILES
       $ZDOTDIR/.zshenv
       $ZDOTDIR/.zprofile
       $ZDOTDIR/.zshrc
       $ZDOTDIR/.zlogin
       $ZDOTDIR/.zlogout
       ${TMPPREFIX}*   (default is /tmp/zsh*)
       /etc/zsh/zshenv
       /etc/zsh/zprofile
       /etc/zsh/zshrc
       /etc/zsh/zlogin
       /etc/zsh/zlogout    (installation-specific - /etc is the default)

Por padrão $ZDOTDIRdeve ser o seu $HOME. Portanto, este comando deve encontrar o arquivo incorreto:

grep 'cp()\|cp ()' ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin /etc/zsh/zshenv \
 /etc/zsh/zprofile /etc/zsh/zshrc /etc/zsh/zlogin 

Eu adicionei o \|já que você também pode ter espaços entre o nome da função e a própria função. Finalmente,@Dennis apontaque os parênteses também podem ser omitidos se você usar a functionpalavra-chave. Então, para ficar ainda mais seguro, faça o seguinte:

grep -E 'function cp|cp *\(\)' ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin \
  /etc/zsh/zshenv /etc/zsh/zprofile /etc/zsh/zshrc /etc/zsh/zlogin 

Responder2

Eu precisava fazer isso hoje e descobri que whence -vgera o arquivo que contém a definição da função.

$ whence -v function_name
function_name is a shell function from /path/to/file

Responder3

Versões mais recentes do zsh (desde 5.4, adicionadas no commit34f70c5) suportam o $functions_sourcearray como parte do zsh/parametermódulo (documentação:) man zshmodules:

functions_source

Esta matriz associativa somente leitura mapeia nomes de funções habilitadas para o nome do arquivo que contém a origem da função.

Para uma função autocarregada que já foi carregada, ou marcada para carregamento automático com um caminho absoluto, ou que teve seu caminho resolvido com ' functions -r', este é o arquivo encontrado para carregamento automático, resolvido para um caminho absoluto.

Para uma função definida no corpo de um script ou arquivo de origem, este é o nome desse arquivo. Neste caso, este é o caminho exato originalmente usado para aquele arquivo, que pode ser um caminho relativo.

Para qualquer outra função, incluindo qualquer função definida em um prompt interativo ou uma função de carregamento automático cujo caminho ainda não tenha sido resolvido, esta é a sequência vazia. No entanto, o elemento hash é relatado como definido apenas enquanto a função estiver presente: as chaves para esse hash são as mesmas de $functions.

Então, você pode fazer

echo $functions_source[cp]

Responder4

A resposta de Terdonjá lhe dei o grepcomando apropriado para capturar todas as variantes possíveis de uma definição de função.

Quero acrescentar mais dois pontos.

  1. Para obter uma lista de arquivos, que sãona verdadelido (por exemplo, um arquivo não padrão pode ser originado de outro arquivo!), você pode invocar zshcom a SOURCE_TRACEopção habilitada:

    $ zsh -o sourcetrace
    +/etc/zshenv:1> <sourcetrace>
    +/home/user/.zshrc:1> <sourcetrace>
    +/home/user/.zcompdump:1> <sourcetrace>
    +/home/user/.zshrc-last:1> <sourcetrace>
    
  2. Com esta abordagem grep'' você não capturará funções que sãocarregado automaticamenteatravés do autoloadembutido. Então, faça uma verificação do seu fpathtambém:

    $ for i ($fpath) { ls -l "$i"/cp }
    

informação relacionada