Другие ответы здесь близки, но все они терпят неудачу, если существует псевдоним или функция с тем же именем, что и проверяемая вами команда.
Вот мое решение:
В tcsh
Используйте команду where
, которая выдает все вхождения имени команды, в том числе встроенную. Затем grep
, чтобы увидеть, говорит ли одна из строк, что она встроенная.
alias isbuiltin 'test \!:1 != "builtin" && where \!:1 | egrep "built-?in" > /dev/null || echo \!:1" is not a built-in"'
В bash
/ zsh
Используйте type -a
, который дает все вхождения имени команды, включая то, является ли она встроенной. Затем grep
, чтобы увидеть, говорит ли одна из строк, что она встроенная.
isbuiltin() {
if [[ $# -ne 1 ]]; then
echo "Usage: $0 command"
return 1
fi
cmd=$1
if ! type -a $cmd 2> /dev/null | egrep '\<built-?in\>' > /dev/null
then
printf "$cmd is not a built-in\n" >&2
return 1
fi
return 0
}
В ksh88
/ ksh93
Откройте вложенную оболочку, чтобы вы могли удалить любые псевдонимы или имена команд с тем же именем. Затем в подоболочке используйте whence -v
. В этом решении также есть дополнительный архаичный синтаксис для поддержки ksh88
.
isbuiltin() {
if [[ $# -ne 1 ]]; then
echo "Usage: $0 command"
return 1
fi
cmd=$1
if (
#Open a subshell so that aliases and functions can be safely removed,
# allowing `whence -v` to see the built-in command if there is one.
unalias "$cmd";
if [[ "$cmd" != '.' ]] && typeset -f | egrep "^(function *$cmd|$cmd\(\))" > /dev/null 2>&1
then
#Remove the function iff it exists.
#Since `unset` is a special built-in, the subshell dies if it fails
unset -f "$cmd";
fi
PATH='/no';
#NOTE: we can't use `whence -a` because it's not supported in older versions of ksh
whence -v "$cmd" 2>&1
) 2> /dev/null | grep -v 'not found' | grep 'builtin' > /dev/null 2>&1
then
#No-op
:
else
printf "$cmd is not a built-in\n" >&2
return 1
fi
}
Использование решения
Как только вы применили вышеупомянутое решение в выбранной вами оболочке, вы можете использовать его следующим образом ...
В командной строке:
$ isbuiltin command
Если команда встроенная, она ничего не печатает; в противном случае он печатает сообщение в stderr.
Или вы можете использовать его в сценарии следующим образом:
if isbuiltin $cmd 2> /dev/null
then
echo "$cmd is a built-in"
else
echo "$cmd is NOT a built-in"
fi