Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

Я понимаю, что это старый вопрос, но ни один из других ответов не делает это так просто, как хотелось бы. Это использует 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

Ответ 3

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

type function_name

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

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

Ответ 4

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

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

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

isFunction __git_ps1 && PS1=__git_ps1

Ответ 5

declare -F 'function_name' > /dev/null

echo $?

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

Ответ 6

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

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

function function_exists
{
    FUNCTION_NAME=$1

    [ -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

Ответ 7

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

help compgen

compgen -A function

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

Ответ 8

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

Ответ 9

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