Actualmente estoy haciendo algunas pruebas unitarias que se ejecutan desde bash. Las pruebas unitarias se inicializan, ejecutan y limpian en un script bash. Este script generalmente contiene funciones init (), execute () y cleanup (). Pero no son obligatorios. Me gustaría probar si están o no definidos.
Hice esto previamente codificando y enviando la fuente, pero parecía estar mal. ¿Hay alguna forma más elegante de hacer esto?
Editar: el siguiente fragmento funciona como un encanto:
fn_exists()
{
LC_ALL=C type $1 | grep -q 'shell function'
}
fn_exists foo || foo() { :; }
type -t
y==
.type test_function
dicetest_function on funktio.
cuando se usa la configuración regional finlandesa yist eine Funktion
cuando se usa el alemán.LC_ALL=C
en el resqueRespuestas:
Creo que estás buscando el comando 'tipo'. Le dirá si algo es una función, una función incorporada, un comando externo o simplemente no está definido. Ejemplo:
fuente
type -t $function
Es el boleto de comida.type [-t]
Es bueno decirle qué es una cosa, pero cuando se prueba si algo es una función, es lento ya que tiene que canalizar para grep o usar backticks, los cuales generan un subproceso.type -t realpath > /dev/shm/tmpfile ; read < /dev/shm/tmpfile
(mal ejemplo). Sin embargo, declarar es la mejor respuesta ya que tiene 0 discos io.fuente
type -t
, puede confiar en el estado de salida. Hace tiempotype program_name > /dev/null 2>&1 && program_name arguments || echo "error"
que veía si podría llamar a algo. Obviamente, eltype -t
método anterior también permite detectar el tipo, no solo si es "invocable".Si declarar es 10 veces más rápido que la prueba, esta parece ser la respuesta obvia.
Editar: a continuación, la
-f
opción es superflua con BASH, no dude en dejarla fuera. Personalmente, tengo problemas para recordar qué opción hace cuál, así que solo uso ambas. -f muestra funciones y -F muestra nombres de funciones.La opción "-F" para declarar hace que solo devuelva el nombre de la función encontrada, en lugar de todo el contenido.
No debería haber ninguna penalización de rendimiento medible por usar / dev / null, y si te preocupa tanto:
O combine los dos, para su propio disfrute sin sentido. Ambos trabajan.
fuente
-F
opción no existe en zsh (útil para la portabilidad)-F
tampoco es realmente necesario: parece suprimir solo la definición de función / cuerpo.cat "$fn" | wc -c
? En cuanto a zsh, si la etiqueta bash no te dio una pista, tal vez la pregunta en sí debería haberlo hecho. "Determinar si existe una función en bash". Además, señalaría que, si bien la-F
opción no existe en zsh, tampoco causa un error, por lo tanto, el uso de -f y -F permite que la verificación tenga éxito tanto en zsh como en bash, que de lo contrario no lo haría. .-F
se usa en zsh para números de coma flotante. No puedo ver por qué el uso lo-F
hace mejor en bash ?! Tengo la impresión de quedeclare -f
funciona igual en bash (con respecto al código de retorno).Tomando prestado de otras soluciones y comentarios, se me ocurrió esto:
Usado como ...
Comprueba si el argumento dado es una función y evita redireccionamientos y otros grepping.
fuente
[ $(type -t "$1")"" == 'function' ]
[[...]]
lugar de[...]
y elimina el hack de citas. También retrocede tenedor, que es lento. Usar en sudeclare -f $1 > /dev/null
lugar.fn_exists() { [ x$(type -t $1) = xfunction ]; }
Desenterrando una publicación anterior ... pero recientemente tuve uso de esto y probé ambas alternativas descritas con:
esto generó:
declarar es un helluvalot más rápido!
fuente
test_type_nogrep () { a () { echo 'a' ;}; local b=$(type a); c=${b//is a function/}; [ $? = 0 ] && return 1 || return 0; }
type
ydeclare
. Se comparatype | grep
condeclare
. Esta es una gran diferencia.Se reduce a usar 'declarar' para verificar la salida o el código de salida.
Estilo de salida:
Uso:
Sin embargo, si la memoria sirve, la redirección a nulo es más rápida que la sustitución de salida (hablando de, el método `cmd` horrible y anticuado debe ser desterrado y $ (cmd) utilizado en su lugar). Y dado que declare devuelve verdadero / falso si se encuentra / no encontrado, y las funciones devuelven el código de salida del último comando en la función, por lo que generalmente no es necesario un retorno explícito, y dado que verificar el código de error es más rápido que verificar un valor de cadena (incluso una cadena nula):
Estilo de estado de salida:
Probablemente sea lo más sucinto y benigno posible.
fuente
isFunction() { declare -F "$1"; } >&-
isFunction() { declare -F -- "$@" >/dev/null; }
Es mi recomendación. También funciona en una lista de nombres (solo tiene éxito si todas son funciones), no da problemas con los nombres que comienzan-
y, a mi lado (bash
4.2.25),declare
siempre falla cuando se cierra la salida>&-
, porque no puede escribir el nombre a stdout en ese casoecho
veces puede fallar con la "llamada interrumpida del sistema" en algunas plataformas. En ese caso, "check && echo yes || echo no" aún puede emitirseno
sicheck
es verdadero.Probar diferentes soluciones:
salidas, por ejemplo:
Entonces
declare -F f
parece ser la mejor solución.fuente
declare -F f
no devuelve un valor distinto de cero si f no existe en zsh, pero bash sí. Ten cuidado al usarlo.declare -f f
, por otro lado, funciona como se espera adjuntando la definición de la función en el stdout (que puede ser molesto ...)test_type3 () { [[ $(type -t f) = function ]] ; }
hay un costo marginal de definir una var local (aunque <10%)De mi comentario sobre otra respuesta (que sigo perdiendo cuando vuelvo a esta página)
fuente
actualizar
fuente
Lo mejoraría para:
Y úsalo así:
fuente
Esto le indica si existe, pero no es que sea una función.
fuente
Me gustó especialmente la solución de Grégory Joseph
Pero lo he modificado un poco para superar el "truco feo entre comillas dobles":
fuente
Es posible usar 'type' sin ningún comando externo, pero debe llamarlo dos veces, por lo que aún termina aproximadamente el doble de lento que la versión 'declare':
Además, esto no funciona en POSIX sh, por lo que es totalmente inútil, excepto como trivia.
fuente