Как Unix ищет исполняемые файлы?

47

Когда исполняется файл, как Unix ищет его? Если в PATH есть несколько исполняемых файлов с одним и тем же именем, какой из них предпочтительнее? Текущий каталог включается в поиск при выполнении файла?

Предположим, executable.shв текущем каталоге есть файл с именем . Будет ли это работать, если оно выполняется $ executedи .не является частью PATH?

Леонид
источник
Упоминание which <executable>команды будет полезно в этой теме.
Бухгалтер م

Ответы:

45

$ PATH ищется от начала до конца, при этом запускается первый соответствующий исполняемый файл. Таким образом, каталоги в начале $ PATH имеют приоритет над теми, которые появляются позже. Исполняемые файлы в текущем каталоге (.) Выполняются только если. находится в $ PATH (чего обычно нет ). Не существует неявного включения текущего каталога в путь поиска.

coneslayer
источник
Странно, что мой $ PATH не содержит ., но, похоже, сначала будет искать из текущего каталога, прежде чем проверять каталоги, определенные в самом $ PATH.
Эрик Ван
19

Для файлов в текущем каталоге вы захотите поставить перед ними ./команду, чтобы команда стала ./executable.sh. Вы никогда не должны иметь .в своем PATH, поскольку это представляет угрозу безопасности, среди других проблем.

Каталоги, которые идут первыми в PATH и ищутся первыми.

Общий порядок для поиска, как это , если я правильно помню:

  • псевдонимы

  • экспортируемые функции

  • встроенные команды оболочки

  • скрипты и двоичные файлы в вашем PATH

Джон Т
источник
7
Я бы добавил хеш - помните, что bash (и, возможно, другие оболочки) хранят хэш недавно использованных команд, чтобы облегчить их поиск. Иногда вам нужно очистить кеш (используя hash -r), если вы меняете путь или местоположение программы.
Рич Гомолка
3
+1 за порядок поиска. Было бы неплохо, если бы вы могли вспомнить источник информации :)
twan163
8

Хотя некоторые другие хорошо ответили на этот вопрос, я хотел бы добавить несколько мыслей:

1) PATH используется только в том случае, если в вызываемом исполняемом файле нет элементов пути. somecommand будет искать в $ PATH, ./somecommandили /usr/bin/somecommand, или ../../bin/somecommandпросто использовать правила каталога, а не PATH

Если в PATH есть несколько исполняемых файлов с одинаковыми именами, какой из них предпочтительнее?

Он останавливается на первом найденном, читая $ PATH слева направо.

Текущий каталог включается в поиск при запуске файла?

Если текущий каталог находится в PATH, то он ищется. Помните, что пустой каталог в PATH включает текущий каталог. например, PATH =: / usr / bin (ведущий пустой) PATH = / usr / bin: (конечный пустой) и PATH = / usr / bin :: / bin (средний пустой) будут эффективно включать текущий рабочий каталог.

Предположим, что в текущем каталоге находится файл с именем executetable.sh. Будет ли это работать, если он выполняется $ выполняется и. не является частью PATH?

Он никогда не найдет его путем поиска PATH. Если текущий каталог не находится в PATH, он не найдет его при поиске PATH.

Это сказало (и извините, чтобы добавить путаницу), если был псевдоним или функция, которая выполнила команду, это будет выполнено. Или, если ваша оболочка имеет кэш местоположения, а исполняемый файл находится в кеше, он может его найти. Таким образом, он никогда не найдет его в PATH, но его можно запустить другими способами.

Рич Гомолка
источник
Спасибо за cacheпримечание, меня почти сводит с ума тот факт, что старый исполняемый файл in /usr/bin/по-прежнему вызывается, а не новый /usr/local/bin, однако он находится слева $PATHдо тех пор, пока я не выйду из системы и снова не выполню вход.
Бухгалтер م
1
@theaccountant в bash вы можете сделать 'hash -r', чтобы очистить кеш оболочки
Rich Homolka
4

Чтобы увидеть, какой путь вы используете в данный момент, просто введите echo $PATHили printenv PATH.

Тогда вы будете знать порядок поиска. Если у вас есть несколько файлов с одним и тем же именем, просто запустите ____, чтобы увидеть.

Ex.

система #> какой grep

/ USR / бен / Grep

классный способ найти файлы, которые работают так, как вы хотите, - это использовать:

по поводу grep

bzgrep (1) - ищет, возможно, bzip2 сжатые файлы для регулярного выражения

egrep (1) - печатать строки, соответствующие шаблону

fgrep (1) - вывести строки, соответствующие шаблону

grep (1) - печатать строки, соответствующие шаблону

и так далее...

MBB
источник
2
Ах да, я забыл функцию whereis, чтобы найти ВСЕ экземпляры файла:> whereis grep
mbb
grep: / bin / grep / usr / bin / grep /usr/share/man/man1/grep.1.gz
mbb
whereisиспользует жестко закодированный список мест, а не $PATH.
Гравитация
@ Grawity Не могли бы вы рассказать об этом?
WinEunuuchs2Unix
-2

@ coneslayer - порядок поиска исполняемого файла по умолчанию - текущий путь, встроенные команды, а затем $ PATH. Таким образом, если функция с именем исполняемый файл уже существует в pwd, то она выполняется. Если нет, то приоритет выполняет поиск встроенных команд оболочки, а затем $ PATH.

процедура
источник
Если вы говорили об раковине Томпсона, раковине Маши или о каком-либо другом окаменелом остатке 40 лет назад, вы могли бы быть правы. Но нет текущей, основной оболочки Unix, которая ищет текущий каталог автоматически.
Скотт
@Scott Итак, путь поиска команды по умолчанию сначала встроен, а затем $ PATH и ищет CWD, только если я дам ./? Я прав?
прок
Ну, псевдонимы, функции и встроенные функции. Затем, если вы укажете путь с помощью команды (включая ./), она будет искать только этот каталог; в противном случае он ищет $PATH.
Скотт