Если вы пишете command
без /
, то оболочка ищет команду $PATH
.
Если вы пишете dir/command
с относительной директорией, есть /
, а оболочка не ищет $PATH
. Это интерпретирует это относительно текущего каталога. dir/command
всегда разрешается до ./dir/command
.
Ввод .
в $PATH
опасен, поскольку вы можете набрать command
, намереваясь запустить /usr/bin/command
, но на самом деле получить ./command
, если он существует в текущем каталоге. Действительно, опасен не только .
: опасен любой относительный путь. $PATH
должен содержать только абсолютные пути.
Итак, вы говорите, что относительные пути должны неявно иметь префикс перед текущим каталогом, в исключительном случае, когда относительный путь пуст, что следует рассматривать как направление поиска в $PATH
?
Да, вы могли бы сказать это. Но я предпочитаю переосмыслить это. Лучший способ думать об этом - понять, что делает shell по сравнению с kernel .
Интерпретация относительных путей обрабатывается ядром неявно. Когда оболочка выполняет системный вызов типа execve("dir/command", ...)
для выполнения программы, ядро знает текущий каталог родительского процесса и разрешает dir/command
относительно него. Оболочка не должна сначала преобразовывать путь в абсолютный. Ядро может обрабатывать как абсолютные, так и относительные пути.
Однако ядро ничего не знает о $PATH
. Это конструкция оболочки. Имейте в виду, что оболочка является частью программного обеспечения более высокого уровня. Оболочка решает, что если вы введете простое имя команды без /
, она не просто передаст эту команду ядру. Если это произойдет, то набрав cat
, вы просто выполните ./cat
. Никто не хочет этого.
Вместо этого оболочка решает, что отсутствие /
означает, что она будет искать команду в $PATH
. Он будет искать /bin
, /usr/bin
, $HOME/bin
и т. Д. Если вы перечислили .
в $PATH
, он также будет искать в текущем каталоге & mdash; не делайте этого! Вы не хотите, чтобы он работал ./cat
. Нет, сэр.
Если оболочка находит исполняемый файл в $PATH
, она преобразует его в абсолютный путь и передает его ядру. Ядро видит execve("/usr/bin/cat", ...)
.
Если это так, и вы знаете это по какой-то формальной спецификации, я был бы признателен за ссылку. Мне нужно знать точно.
См. Справочную страницу bash :
Если имя команды не содержит косых черт, оболочка пытается найти его. ...
Если имя ... не содержит косых черт, bash ищет в каждом элементе PATH
каталог, содержащий исполняемый файл с этим именем. …
Если поиск выполнен успешно или если имя команды содержит одну или несколько косых черт, оболочка выполняет указанную программу….