Какая разница между чем и где

16

В чем разница между whereи whichкоманды оболочки? вот несколько примеров

 ~  where cc
/usr/bin/cc
/usr/bin/cc
~  which cc
/usr/bin/cc

и

  ~  which which
which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
/usr/bin/which
  ~  which where
/usr/bin/which: no where in (/usr/local/bin:/bin:/usr/bin:/home/bnikhil/bin:/bin)

также

  ~  where which
which: aliased to alias | /usr/bin/which --tty-only --read-alias --show-dot
 --show-tilde
which: shell built-in command
/usr/bin/which
/usr/bin/which
  ~  where where
where: shell built-in command

Мне кажется, что они делают то же самое, будучи встроенным в оболочку, не совсем понимая, чем это отличается от команды?

Нихилу
источник

Ответы:

11

zshэто одна из немногих оболочек (другие tcsh( whichвозникли как cshсценарий для cshпользователей, который также имел свои ограничения, tcshсделал его встроенным в качестве улучшения)), где whichделает что-то разумное, так как это встроенная оболочка, но каким-то образом вы или ваша ОС (через какой-то rcфайл) сломал его, заменив его вызовом системной whichкоманды, которая не может сделать ничего разумного, так как не имеет доступа к внутренним компонентам оболочки, поэтому не может знать, как эта оболочка интерпретирует имя команды ,

В Zsh, все which, type, whenceи whereявляются встроенными командами, которые все используются , чтобы узнать о том, что команды, но с разными выходами. Они все там по исторической причине, вы можете получить все их поведение с различными флагами для whenceкоманды.

Вы можете получить подробную информацию о том, что каждый из них делает, запустив:

info -f zsh --index-search=which

Или введите info zsh, затем вызовите индекс с помощью iи введите встроенное имя (завершение доступно).

И избегайте использования /usr/bin/which. Там нет оболочки в настоящее время, где это which необходимо. Как говорит Тимоти, используйте встроенную функцию, которая предусмотрена вашей оболочкой. Большинство оболочек POSIX будут иметь typeкоманду, и вы можете использовать command -vее только для того, чтобы получить путь к команде (хотя оба typeи command -vявляются необязательными в POSIX (но не в Unix и больше не в LSB), они доступны в большинстве, если не во всех Борновые снаряды, с которыми вы, вероятно, когда-либо сталкивались).

(Кстати, похоже, /usr/binдважды появляется в вашем $PATH, вы могли бы добавить typeset -U pathк вашему ~/.zshrc)

Стефан Шазелас
источник
2
Это возникло и в предыдущем вопросе. Чтобы расширить эту точку, вы всегда должны использовать оболочку, встроенную в команду, где она существует. Так что в bash используйте «type» вместо «which».
Тим Б
Отличный ответ и спасибо за этот совет тоже.
nikhil