which, type, command -v
Что именно запустится по имени команды — файл из PATH, встроенная команда, алиас или функция
Когда ты набираешь ls, оболочка ищет это имя по порядку: алиас → функция → встроенная команда (builtin) → исполняемый файл в каталогах из $PATH. Три инструмента отвечают на вопрос «что запустится»:
type— встроенная команда bash, знает обо всём: алиасы, функции, builtins, файлы;command -v— то же коротко и по POSIX, работает в любойsh; лучший выбор для скриптов;which— отдельная программа, ищет только файлы в$PATHи ничего не знает о том, что определено в оболочке.
Синтаксис
type [-afptP] имя…
command -v имя
command -V имя
which [-a] [-s] имя…
type
| Опция | Что делает |
|---|---|
| (без опций) | человекочитаемо: ls is /usr/bin/ls, cd is a shell builtin, ll is aliased to 'ls -l', текст функции |
-t | одно слово: alias, function, builtin, keyword, file; пусто и код 1, если не найдено |
-a | все варианты по порядку: алиас, builtin и все файлы в PATH |
-p | путь к файлу, только если по имени запустится файл (для builtin — пусто) |
-P | путь к файлу в PATH, даже если есть builtin или алиас с тем же именем |
-f | не учитывать функции |
keyword — служебные слова синтаксиса: if, for, while, [[. «ls is hashed (/usr/bin/ls)» значит, что путь уже запомнен (см. hash ниже).
command
| Форма | Что делает |
|---|---|
command -v имя | путь к файлу; для builtin, функции, ключевого слова — само имя; для алиаса — строка alias ll='ls -l'. Не найдено — пусто и код 1 |
command -V имя | подробное описание, как у type |
command имя args | запустить, минуя алиасы и функции с этим именем |
command -p … | искать по стандартному PATH, а не по текущему $PATH |
which
| Опция | Что делает |
|---|---|
-a | все совпадения во всех каталогах PATH, а не только первое |
-s | ничего не печатать, только код возврата |
Код возврата: 0 — все имена найдены, 1 — хотя бы одно не найдено (найденные всё равно печатаются).
hash — кеш путей
Bash запоминает, где нашёл команду, и в следующий раз не ищет её в PATH.
| Команда | Что делает |
|---|---|
hash | таблица: сколько раз запускалась и откуда |
hash -r | забыть всё — после установки, переноса или удаления программ |
hash -d имя | забыть одно имя |
hash -t имя | показать запомненный путь |
Примеры
# что такое ls, cd и ll в этой оболочке
type ls cd ll
type -t cd # builtin
# все echo: встроенная и файл
type -a echo
# проверить в скрипте, что программа установлена
if ! command -v jq >/dev/null 2>&1; then
echo "установи jq" >&2
exit 1
fi
# полный путь к программе (для sudoers, cron, systemd)
command -v systemctl
# куда на самом деле ведёт команда через цепочку ссылок
readlink -f "$(command -v python3)"
# какие копии есть в разных каталогах PATH — кто «затеняет» кого
which -a python3
# вызвать настоящий ls в обход алиаса или функции ls
command ls
\ls
# после переноса программы в другой каталог оболочка ищет её по старому пути
hash -r
Подводные камни
whichне видит алиасы, функции и builtins.which cdничего не печатает и возвращает 1, аwhich echoпоказывает/usr/bin/echo, хотя bash выполнит встроенныйecho. Чтобы понять, что запустится на самом деле, используйtype.whichна разных системах ведёт себя по-разному (в Debian/Ubuntu это скрипт, в других дистрибутивах — бинарник с другими опциями и сообщениями). В скриптах вместо него —command -v.- Устаревший кеш. Если программу перенесли, bash продолжит запускать её по старому пути: «No such file or directory» с кодом 127, хотя
whichнаходит её на новом месте. Помогаетhash -rили новая оболочка. - Первое совпадение в PATH выигрывает. Файл в
/usr/local/binперекрывает одноимённый в/usr/bin. Если запускается «не та версия» —type -a имя. command -vдля алиаса выводит строкуalias ll='ls -l', а не путь. Если нужен именно файл —type -P имя.whereis— другой инструмент: ищет бинарник, исходники и man-страницы в стандартных каталогах, а не в твоём PATH.