Actuellement, je fais des tests unitaires qui sont exécutés à partir de bash. Les tests unitaires sont initialisés, exécutés et nettoyés dans un script bash. Ce script contient généralement des fonctions init (), execute () et cleanup (). Mais ils ne sont pas obligatoires. Je voudrais tester s'ils sont définis ou non.
Je l'ai fait précédemment en greffe et en semant la source, mais cela semblait faux. Y a-t-il une manière plus élégante de faire cela?
Edit: Le sniplet suivant fonctionne comme un charme:
fn_exists()
{
LC_ALL=C type $1 | grep -q 'shell function'
}
fn_exists foo || foo() { :; }
type -t
et==
.type test_function
dittest_function on funktio.
lors de l'utilisation de la langue finlandaise etist eine Funktion
lors de l'utilisation de l'allemand.LC_ALL=C
à la resqueRéponses:
Je pense que vous recherchez la commande «type». Il vous dira si quelque chose est une fonction, une fonction intégrée, une commande externe ou tout simplement non définie. Exemple:
la source
type -t $function
est le ticket repas.type [-t]
C'est bien de vous dire ce qu'est une chose, mais lorsque vous testez si quelque chose est une fonction, c'est lent car vous devez rediriger vers grep ou utiliser des backticks, qui génèrent tous deux un sous-processus.type -t realpath > /dev/shm/tmpfile ; read < /dev/shm/tmpfile
(mauvais exemple). Cependant, déclarer est la meilleure réponse car il a 0 disque io.la source
type -t
, vous pouvez vous fier à l'état de sortie à la place. J'ai depuis longtemps l'habitudetype program_name > /dev/null 2>&1 && program_name arguments || echo "error"
de voir si je pourrais appeler quelque chose. Évidemmenttype -t
, la méthode et la méthode ci-dessus permettent également de détecter le type, pas seulement s'il est "appelable".Si déclarer est 10 fois plus rapide que le test, cela semblerait la réponse évidente.
Edit: Ci-dessous, l'
-f
option est superflue avec BASH, n'hésitez pas à la laisser de côté. Personnellement, j'ai du mal à me souvenir quelle option fait quoi, alors j'utilise simplement les deux. -f montre les fonctions et -F montre les noms des fonctions.L'option "-F" à déclarer l'amène à ne renvoyer que le nom de la fonction trouvée, plutôt que le contenu entier.
Il ne devrait y avoir aucune pénalité mesurable en termes de performances pour l'utilisation de / dev / null, et si cela vous inquiète autant:
Ou combinez les deux, pour votre propre plaisir inutile. Ils fonctionnent tous les deux.
la source
-F
option des n'existe pas dans zsh (utile pour la portabilité)-F
aussi n'est pas vraiment nécessaire: il semble supprimer uniquement la définition / le corps de la fonction.cat "$fn" | wc -c
? Quant à zsh, si la balise bash ne vous a pas indiqué, peut-être que la question elle-même devrait avoir. "Détermine si une fonction existe dans bash". Je voudrais en outre souligner que, bien que l'-F
option n'existe pas dans zsh, elle ne provoque pas non plus d'erreur.Par conséquent, l'utilisation de -f et -F permet à la vérification de réussir à la fois dans zsh et bash, ce qui sinon .-F
est utilisé dans zsh pour les nombres à virgule flottante. Je ne vois pas pourquoi utiliser le-F
rend meilleur dans bash?! J'ai eu l'impression que çadeclare -f
marche de la même façon en bash (concernant le code retour).En empruntant à d'autres solutions et commentaires, j'ai trouvé ceci:
Utilisé comme ...
Il vérifie si l'argument donné est une fonction et évite les redirections et autres grepping.
la source
[ $(type -t "$1")"" == 'function' ]
[[...]]
place[...]
et débarrassez-vous du hack de devis. Également à la fourche, ce qui est lent. Utilisezdeclare -f $1 > /dev/null
plutôt.fn_exists() { [ x$(type -t $1) = xfunction ]; }
Récupérer un ancien article ... mais j'ai récemment eu recours à cela et j'ai testé les deux alternatives décrites avec:
cela a généré:
déclarer est un helluvalot plus rapide!
la source
test_type_nogrep () { a () { echo 'a' ;}; local b=$(type a); c=${b//is a function/}; [ $? = 0 ] && return 1 || return 0; }
type
etdeclare
. Il comparetype | grep
avecdeclare
. C'est une grande différence.Cela revient à utiliser 'declare' pour vérifier la sortie ou le code de sortie.
Style de sortie:
Usage:
Cependant, si la mémoire est bonne, la redirection vers null est plus rapide que la substitution de sortie (en parlant de, la méthode horrible et obsolète `cmd` devrait être bannie et $ (cmd) utilisée à la place.) Et puisque declare retourne vrai / faux si trouvé / introuvable, et les fonctions renvoient le code de sortie de la dernière commande de la fonction, donc un retour explicite n'est généralement pas nécessaire, et comme la vérification du code d'erreur est plus rapide que la vérification d'une valeur de chaîne (même une chaîne nulle):
Style de statut de sortie:
C'est probablement aussi succinct et bénin que possible.
la source
isFunction() { declare -F "$1"; } >&-
isFunction() { declare -F -- "$@" >/dev/null; }
est ma recommandation. Il fonctionne également sur une liste de noms (ne réussit que si tous sont des fonctions), ne pose aucun problème avec les noms commençant par-
et, à mes côtés (bash
4.2.25),declare
échoue toujours lorsque la sortie est fermée avec>&-
, car il ne peut pas écrire le nom à stdout dans ce casecho
peut parfois échouer avec un "appel système interrompu" sur certaines plates-formes. Dans ce cas, "check && echo yes || echo no" peut toujours afficherno
sicheck
est vrai.Tester différentes solutions:
sorties par exemple:
Cela
declare -F f
semble donc être la meilleure solution.la source
declare -F f
ne renvoie pas de valeur non nulle si f n'existe pas sur zsh, mais bash oui. Soyez prudent en l'utilisant.declare -f f
, d'autre part, fonctionne comme prévu en attachant la définition de la fonction sur le stdout (ce qui peut être ennuyeux ...)test_type3 () { [[ $(type -t f) = function ]] ; }
qu'il y ait un coût marginal de définition d'une var locale (bien que <10%)De mon commentaire sur une autre réponse (qui me manque toujours en revenant sur cette page)
la source
mettre à jour
la source
Je l'améliorerais pour:
Et utilisez-le comme ceci:
la source
Cela vous indique s'il existe, mais pas que c'est une fonction
la source
J'ai particulièrement aimé la solution de Grégory Joseph
Mais je l'ai un peu modifié pour surmonter le "truc laid des guillemets doubles":
la source
Il est possible d'utiliser 'type' sans aucune commande externe, mais vous devez l'appeler deux fois, donc cela finit toujours par être environ deux fois plus lent que la version 'declare':
De plus, cela ne fonctionne pas dans POSIX sh, donc cela ne vaut absolument rien sauf pour des anecdotes!
la source