Проверьте, существует ли функция из сценария bash [duplicate]

17

Как определить, определена ли функция в сценарии bash?

Я пытаюсь сделать мой .bash_login сценарий переносимым между системами, поэтому я хочу добавить логику только для вызова функции, если она существует.

Я хочу добавить __git_ps1() в PS1 , только если эта функция существует в этой системе. Эта функция обычно определяется в git-completion.bash , которая поставляется с источником git, или одним из сценариев завершения bash, которые устанавливаются ports / apt.

    
задан csexton 17.06.2009 в 16:50
источник

9 ответов

10
if type __git_ps1 | grep -q '^function$' 2>/dev/null; then
    PS1=whatever
fi
    
ответ дан chaos 17.06.2009 в 17:00
источник
10

Я понимаю, что это старый вопрос, но ни один из других ответов не делает это так просто, как хотелось бы. Это использует type -t (как предложено в комментарии Чена Леви) как эффективный тип теста, но затем использует сравнение строк оболочки, а не вызов grep.

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

И чтобы сделать это еще дальше, он также работает косвенно:

funcname=do_it_special_$somehow
if [ "$(type -t $funcname)" != 'function' ]; then
    funcname=do_it_normal
fi
$funcname arg1 arg2
    
ответ дан Trevor Robinson 14.09.2011 в 00:07
источник
8

Вы можете сделать это, используя:

type function_name

in вернет ваше определение функции в том случае, если оно существует. Таким образом, вы можете проверить, когда вывод пуст или нет.

PS. Еще лучше, что я только что проверил, будет выводиться эта функция, которая не существует в противном случае для тела выходной функции.

    
ответ дан Artem Barger 17.06.2009 в 17:00
источник
5

Если вам нужна версия, совместимая с /bin/sh , вы не можете использовать typeset или declare для проверки определения функции, поскольку она не является встроенной оболочкой. Также опция -f для type может быть недоступна в некоторых системах.

Решение, которое я представляю, частично описано в других ответах:

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

isFunction __git_ps1 && PS1=__git_ps1
    
ответ дан marcel 08.11.2011 в 12:55
источник
4

declare -F 'function_name' & gt; / DEV / нуль

echo $?

$? результат имеет значение 0, если функция существует, 1 в противном случае

    
ответ дан Fritz G. Mehner 17.06.2009 в 17:02
источник
2

Я думаю, что лучше использовать declare, даже если он немного медленнее, чем тип. Тип также подходит для псевдонимов или скриптов, которые находятся в PATH.

Я использую это:

function function_exists
{
    FUNCTION_NAME=

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

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

    return $?
}

Так что позже в моих сценариях я легко вижу, что происходит:

if function_exists __git_ps1
then
    PS1=__git_ps1
fi

Или даже неподвижный однострочный слой:

function_exists __git_ps1 && PS1=__git_ps1
    
ответ дан Jacobo de Vera 28.07.2009 в 22:52
источник
1

Вы можете перечислить все доступные функции или проверить отдельные функции с помощью compgen:

help compgen

compgen -A function

compgen -A function myfunc 1>/dev/null && echo 'myfunc already exists' || exit 1
    
ответ дан tim 05.04.2011 в 15:25
источник
0
if declare -F | grep __git_ps1$
then
    PS1=whatever
fi
    
ответ дан Jaime Soriano 17.06.2009 в 17:11
источник
0

Примечание. busybox (минимализм в одной реализации оболочки, полезный для Windows, например) имеет тип «type», но «type -t» печатает неправильную вещь, поэтому я просто проверяю возвращаемое значение типа, чтобы узнать, можно ли что-то вызвать , busybox также не объявляет.

    
ответ дан Reed Hedges 31.05.2012 в 18:30
источник