Проверка bash и csh, если команда встроена
Как я могу проверить bash и csh, если команды встроены? Есть ли метод, совместимый с большинством оболочек?
5 ответов
вы можете попробовать использовать which
в csh или type
в bash. Если что-то является встроенной командой, она так и скажет; в противном случае вы получите местоположение команды на своем пути.
в csh:
# which echo
echo: shell built-in command.
# which parted
/sbin/parted
в bash:
# type echo
echo is a shell builtin
# type parted
parted is /sbin/parted
type
также может показать что-то вроде этого:
# type clear
clear is hashed (/usr/bin/clear)
...это означает, что это не встроенный, но что bash сохранил свое местоположение в хэш-таблице, чтобы ускорить доступ к нему;(немного) больше в этот пост в Unix & Linux.
в bash, вы можете использовать с . Полную информацию можно найти в bash-builtins
man-страница, но соответствующий бит:
тип -t имя
если
-t
используется опция, тип печатает строку, которая является одной изalias
,keyword
,function
,builtin
илиfile
если имя-это псевдоним, зарезервированное слово оболочки, функция, встроенный или дисковый файл соответственно. Если имя не найдено, то ничего нет печатается, и возвращается состояние выхода false.
следовательно, вы можете использовать такие как:
if [[ "$(type -t read)" == "builtin" ]] ; then echo read ; fi
if [[ "$(type -t cd)" == "builtin" ]] ; then echo cd ; fi
if [[ "$(type -t ls)" == "builtin" ]] ; then echo ls ; fi
что привело бы к выходу:
read
cd
на csh
, вы можете использовать:
which command-name
если он встроенный, он скажет так. Не уверен, что это работает так же для bash. Но мы осторожны с псевдонимами. Для этого могут быть варианты.
другие ответы здесь близки, но все они терпят неудачу, если есть псевдоним или функция с тем же именем, что и команда, которую вы проверяете.
вот мое решение:
на 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: command"
return 1
fi
cmd=
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: command"
return 1
fi
cmd=
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