2009-06-17 14 views
18

¿Cómo puedo determinar si una función ya está definida en un script bash?Compruebe si existe una función desde un script bash

Estoy intentando hacer que mi script .bash_login sea portátil entre sistemas, por lo que quiero agregar lógica para llamar solo a una función si existe.

Quiero agregar __git_ps1() a PS1 solo si esa función existe en ese sistema. Esta función normalmente se define en git-completion.bash que viene con git source, o por uno de los scripts de finalización de bash que ports/apt instala.

Respuesta

10
if type __git_ps1 | grep -q '^function$' 2>/dev/null; then 
    PS1=whatever 
fi 
+0

Usar 'type' fue mucho más rápido que' declare' - gracias. – csexton

+4

Esto es casi correcto, pero también devolverá "verdadero" si '__get_ps1' es un alias, incorporado, etc. Utilice' si escribe -t nombre_función | grep -q "^ función $"; luego ... fi', para asegurarse de que '__git_ps1' es una función. –

+0

@ChenLevy: editado por. – chaos

8

Puede hacerlo utilizando:

type function_name 

en le devolverá la definición de una función en el caso de que exista. Por lo tanto, puede verificar si la salida está vacía o no.

PS. Aún mejor, acabo de comprobar que saldrá esa función que no existe, de lo contrario el cuerpo de la función de salida.

4

declaran -F 'function_name'>/dev/null

echo $?

$? resultado tiene el valor 0 si la función existe, de lo contrario 1

0
if declare -F | grep __git_ps1$ 
then 
    PS1=whatever 
fi 
2

creo que es mejor utilizar declarar, incluso si es un poco más lenta que la de tipo. Escriba suceeds también para alias o scripts que están en la RUTA.

estoy usando esto:

function function_exists 
{ 
    FUNCTION_NAME=$1 

    [ -z "$FUNCTION_NAME" ] && return 1 

    declare -F "$FUNCTION_NAME" > /dev/null 2>&1 

    return $? 
} 

Así adelante en mis guiones que fácilmente puede ver lo que está pasando:

if function_exists __git_ps1 
then 
    PS1=__git_ps1 
fi 

o incluso el sigue siendo legible de una sola línea:

function_exists __git_ps1 && PS1=__git_ps1 
1

Puede enumerar todas las funciones disponibles o verificar funciones individuales con compgen:

help compgen 

compgen -A function 

compgen -A function myfunc 1>/dev/null && echo 'myfunc already exists' || exit 1 
11

Me doy cuenta de que esta es una vieja pregunta, pero ninguna de las otras respuestas lo hace tan simple como me gustaría. Esto usa type -t (como se sugiere en un comentario de Chen Levy) como una prueba de tipo eficiente, pero luego usa la comparación de cadenas de shell en lugar de invocar grep.

if [ "$(type -t somefunc)" = 'function' ]; then 
    somefunc arg1 arg2 
fi 

Y para dar un paso más allá, sino que también funciona indirectamente:

funcname=do_it_special_$somehow 
if [ "$(type -t $funcname)" != 'function' ]; then 
    funcname=do_it_normal 
fi 
$funcname arg1 arg2 
+0

Me gusta mucho esta solución, aunque siento que los apoyos de la cuerda se sienten incómodos. De todos modos, ciertamente usaré esto. – csexton

+0

@csexton Puedes usar '" $ (type -t somefunc) "' en lugar de backticks. – wisbucky

5

Si necesita una versión compatible /bin/sh, no se puede utilizar typeset o declare para comprobar si una definición de función, ya que no es un shell incorporado. Además, la opción -f a type podría no estar disponible en algunos sistemas.

La solución presento está cubierta en parte en ya otras respuestas:

isFunction() { 
    type $1 | head -1 | egrep "^$1.*function\$" >/dev/null 2>&1; 
    return; 
} 

isFunction __git_ps1 && PS1=__git_ps1 
0

Nota, busybox (minimalista todo en una implementación shell, útil en Windows, por ejemplo) tiene "tipo" pero "-t tipo" imprime la cosa incorrecta, así que solo compruebo el valor de retorno de tipo para ver si algo es invocable. busybox tampoco tiene declarar.

Cuestiones relacionadas