Existe uma maneira embutida (ou pelo menos simples) de verificar a existência de uma função acessível através do $ FPATH?

1

Eu quero definir uma função foo em um script (destinado a ser originado ), mas apenas com a condição de que algum executável, função interna do shell ou alias desse nome já não "existe".

A definição de "existência", neste caso, não é totalmente trivial (daí os alarm-quotes).

Como primeira aproximação, minha definição operacional é que foo existe se which foo retornar algo diferente de foo not found . Isso funciona para a maioria dos casos em que estou interessado ...

% which cat
/bin/cat
% which cd
cd: shell built-in command
% which zargs
zargs () {
    # undefined
    builtin autoload -XU
}
% which grep
grep: aliased to grep --color=always

... mas não captura funções definidas em arquivos acessíveis por $FPATH :

% which zargs
zargs not found

É claro que eu poderia rolar meu próprio wrapper em torno de which para também verificar as funções em $FPATH (explicitamente iterando sobre isso, etc.), mas aprendi (ou talvez aprendi demais) que, quando se trata de programação shell, nada é tão simples quanto parece ... Portanto, se já existe 1) uma maneira integrada de realizar este teste de existência para as funções disponíveis; ou pelo menos 2) um idioma estabelecido para fazer isso, prefiro muito mais seguir esse caminho.

    
por kjo 17.10.2015 / 17:29

1 resposta

2

Uma função acessível por fpath não "existe" no sentido em que pode ser invocada. Ele deve ser carregado automaticamente primeiro, após o qual which (e qualquer outro método para testar a existência de uma função) reportará uma definição de stub que carrega automaticamente a definição real.

% zargs
zsh: command not found: zargs
% autoload zargs
% which zargs
zargs () {
        # undefined
        builtin autoload -X
}

which foo teste com precisão se foo pode ser usado como um nome de comando, exceto por qualquer que seja o command_not_found_handler . Como command_not_found_handler pode conter código arbitrário, não há como prever o que isso fará; e como ele executa o comando substituto se encontrar um, não há como verificar o que ele faria sem executar nada.

Se o seu código for específico de zsh, você pode usar whence em vez de which (ou whence -w para obter saída terser, não há nenhuma opção para torná-lo silencioso), que é um wrapper em torno de whence . Se você quiser que seu código seja utilizável em outros shells ao estilo Bourne / POSIX, use type , não which .

function exists {
  whence -w $1 >/dev/null
}

Se a sua definição de "existir" inclui funções que podem ser carregadas automaticamente, mas ainda não estão implementadas, implemente código que detecte funções que possam ser carregadas automaticamente, mas que ainda não estejam: traverse $fpath explicitamente.

    
por 18.10.2015 / 00:31

Tags