Как я могу проверить bash и csh, если команды встроены? Есть ли метод, совместимый с большинством оболочек?
Проверка в bash и csh, если команда встроена
Ответ 1
Вы можете попробовать использовать which
в csh или type
в bash. Если что-то есть встроенная команда, это скажет так; в противном случае вы получите местоположение команды в своем PATH.
В 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.
Ответ 2
В bash вы можете использовать команду type
с опцией -t
. Полную информацию можно найти на странице руководства bash-builtins
, но соответствующий бит:
тип -t name
Если используется опция
-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
Ответ 3
Для bash
используйте type command
Ответ 4
Для csh
вы можете использовать:
which command-name
Если он встроен, он это скажет. Не уверен, что он работает одинаково для bash. Однако мы осторожны с псевдонимами. Для этого могут быть варианты.
Ответ 5
Другие ответы здесь близки, но все они терпят неудачу, если есть псевдоним или функция с тем же именем, что и команда, которую вы проверяете.
Здесь мое решение:
В 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 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.
Или вы можете использовать его как в script:
if isbuiltin $cmd 2> /dev/null
then
echo "$cmd is a built-in"
else
echo "$cmd is NOT a built-in"
fi