Проверка в bash и csh, встроена ли команда - PullRequest
15 голосов
/ 13 сентября 2011

Как я могу проверить в bash и csh, встроены ли команды?Есть ли метод, совместимый с большинством оболочек?

Ответы [ 5 ]

12 голосов
/ 13 сентября 2011

Вы можете попробовать использовать 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 .

10 голосов
/ 13 сентября 2011

В bash вы можете использовать команду type с опцией -t. Полную информацию можно найти на справочной странице bash-builtins, но соответствующий бит:

тип -т имя

Если используется опция -t, type печатает строку, которая является одной из alias, keyword, function, builtin или file, если name является псевдонимом, зарезервированным словом оболочки, функция, встроенный или дисковый файл, соответственно. Если имя не найдено, ничего не печатается, и возвращается состояние выхода 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
4 голосов
/ 13 сентября 2011

Для bash, используйте type command

2 голосов
/ 13 сентября 2011

Для csh вы можете использовать:

which command-name

Если он встроенный, он скажет об этом. Не уверен, что он работает так же для Bash. Мы осторожны с псевдонимами. Для этого могут быть варианты.

1 голос
/ 11 мая 2015

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

Вот мое решение:

В 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
...