Atualmente estou fazendo alguns testes de unidade que são executados a partir do bash. Os testes de unidade são inicializados, executados e limpos em um script bash. Esse script geralmente contém as funções init (), execute () e cleanup (). Mas eles não são obrigatórios. Eu gostaria de testar se eles estão ou não definidos.
Eu fiz isso anteriormente, contornando e seduzindo a fonte, mas parecia errado. Existe uma maneira mais elegante de fazer isso?
Editar: O sniplet a seguir funciona como um encanto:
fn_exists()
{
LC_ALL=C type $1 | grep -q 'shell function'
}
fn_exists foo || foo() { :; }
type -t
e==
.type test_function
diztest_function on funktio.
ao usar a localidade finlandesa eist eine Funktion
ao alemão.LC_ALL=C
noRespostas:
Eu acho que você está procurando o comando 'type'. Indica se algo é uma função, função interna, comando externo ou simplesmente não definido. Exemplo:
fonte
type -t $function
é o bilhete da refeição.type [-t]
É bom dizer o que é uma coisa, mas ao testar se algo é uma função, é lento, pois você precisa canalizar para grep ou usar backticks, os quais geram um subprocesso.type -t realpath > /dev/shm/tmpfile ; read < /dev/shm/tmpfile
(exemplo ruim). No entanto, declare é a melhor resposta, pois possui 0 disco io.fonte
type -t
, você pode confiar no status de saída. Há muito tempotype program_name > /dev/null 2>&1 && program_name arguments || echo "error"
que vejo se consigo ligar para alguma coisa. Obviamente, otype -t
método e o método acima também permitem detectar o tipo, não apenas se é "exigível".Se declarar é 10x mais rápido que o teste, esta parece a resposta óbvia.
Edit: Abaixo, a
-f
opção é supérflua com o BASH, fique à vontade para deixar de fora. Pessoalmente, tenho dificuldade em lembrar qual opção faz qual, então apenas uso as duas. -f mostra funções e -F mostra nomes de funções.A opção "-F" a declarar faz com que retorne apenas o nome da função encontrada, em vez de todo o conteúdo.
Não deve haver nenhuma penalidade de desempenho mensurável pelo uso de / dev / null e se isso lhe preocupa tanto:
Ou combine os dois, para seu próprio prazer inútil. Ambos trabalham.
fonte
-F
opção des não existir em zsh (útil para portabilidade)-F
também não é realmente necessário: parece suprimir apenas a definição / corpo da função.cat "$fn" | wc -c
? Quanto ao zsh, se a tag bash não o identificou, talvez a pergunta em si deva ter. "Determinar se existe uma função no bash". Gostaria de salientar ainda que, embora a-F
opção não exista no zsh, ela também não causa um erro, portanto, o uso de -f e -F permite que a verificação seja bem-sucedida no zsh e no bash, caso contrário, não existiria. .-F
é usado no zsh para números de ponto flutuante. Não vejo por que usar-F
melhora no bash ?! Tive a impressão de quedeclare -f
funciona da mesma forma no bash (em relação ao código de retorno).Tomando emprestado de outras soluções e comentários, eu vim com isso:
Usado como ...
Ele verifica se o argumento fornecido é uma função e evita redirecionamentos e outros grepping.
fonte
[ $(type -t "$1")"" == 'function' ]
[[...]]
vez de[...]
e livre-se da citação hack. Também reticula o garfo, que é lento. Use emdeclare -f $1 > /dev/null
vez disso.fn_exists() { [ x$(type -t $1) = xfunction ]; }
Dragagem de um post antigo ... mas recentemente eu usei isso e testei as duas alternativas descritas com:
isso gerou:
declarar é muito mais rápido!
fonte
test_type_nogrep () { a () { echo 'a' ;}; local b=$(type a); c=${b//is a function/}; [ $? = 0 ] && return 1 || return 0; }
type
edeclare
. Comparatype | grep
comdeclare
. Isso é uma grande diferença.Tudo se resume a usar 'declare' para verificar o código de saída ou saída.
Estilo de saída:
Uso:
No entanto, se a memória servir, o redirecionamento para null é mais rápido que a substituição da saída (falando sobre, o terrível e desatualizado método `cmd` deve ser banido e $ (cmd) usado em seu lugar.) E como declare retorna true / false se encontrado / não encontrado e as funções retornam o código de saída do último comando na função, portanto, um retorno explícito geralmente não é necessário e, uma vez que a verificação do código de erro é mais rápida do que a verificação de um valor de sequência (mesmo uma sequência nula):
Estilo de status de saída:
Provavelmente é o mais sucinto e benigno possível.
fonte
isFunction() { declare -F "$1"; } >&-
isFunction() { declare -F -- "$@" >/dev/null; }
é a minha recomendação. Também funciona em uma lista de nomes (é bem-sucedida apenas se todas forem funções), não apresenta problemas com nomes iniciados por-
e, ao meu lado (bash
4.2.25),declare
sempre falha quando a saída é fechada>&-
, porque não pode escrever o nome para stdout nesse casoecho
às vezes isso pode falhar com a "chamada interrompida do sistema" em algumas plataformas. Nesse caso, "check && echo yes || echo no" ainda pode gerar saídano
secheck
for verdadeiro.Testando diferentes soluções:
saídas, por exemplo:
Então
declare -F f
parece ser a melhor solução.fonte
declare -F f
não retorna um valor diferente de zero se f não existir no zsh, mas sim no bash. Cuidado ao usá-lo.declare -f f
, Por outro lado, funciona como esperado anexando a definição da função no stdout (que pode ser irritante ...)test_type3 () { [[ $(type -t f) = function ]] ; }
há um custo marginal de definir uma var local (embora <10%)Do meu comentário sobre outra resposta (que continuo faltando quando volto a esta página)
fonte
atualizar
fonte
Eu o melhoraria para:
E use-o assim:
fonte
Isso informa se existe, mas não é uma função
fonte
Eu particularmente gostei da solução de Grégory Joseph
Mas eu o modifiquei um pouco para superar o "truque feio de aspas duplas":
fonte
É possível usar 'type' sem nenhum comando externo, mas você deve chamá-lo duas vezes, para que ainda termine duas vezes mais lento que a versão 'declare':
Além disso, isso não funciona no POSIX sh, por isso é totalmente inútil, exceto como trivialidades!
fonte