1

Иногда мне приходится указывать полный путь, потому что $ PATH, по-видимому, не используется:

####            I have `virtualenv` and it's on my path            ####

$ virtualenv --version      # `virtualenv` is on my path
1.7.1.2
$ which virtualenv          # further details
/usr/bin/virtualenv
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

####               However, I can't `stat virtualenv`:             ####

$ stat virtualenv
stat: cannot stat `virtualenv': No such file or directory

####              I have to use `stat `which $BINARY``               ####

$ stat `which virtualenv`
  File: `/usr/bin/virtualenv'
  Size: 54              Blocks: 8          IO Block: 4096   regular file
Device: ca01h/51713d    Inode: 22860       Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2012-11-28 23:48:03.919400541 -0500
Modify: 2012-04-23 06:34:09.000000000 -0400
Change: 2012-11-28 17:24:31.335400569 -0500
 Birth: -
$ 

Почему я должен использовать which virtualenv если он на моем пути?

3 ответа3

5

$PATH используется только при выполнении команд. Когда оболочке приходится искать команду для выполнения, она обращается к $PATH просматривает список каталогов в $PATH и выбирает первый исполняемый файл (с соответствующим битом выполнения, установленным в разрешениях), соответствующий указанному имени, и выполняет Это.

Когда вы запускаете stat virtualenv , вы передаете virtualenv в качестве аргумента программе stat . Предполагая, что stat написан на C, он рассматривает virtualenv в качестве аргумента в основном методе программы:

int main(int argc, char** argv)

argv содержит два элемента: index 0 - это команда, которую вы использовали для вызова самой программы, так что это "stat". Индекс 1 - это первый аргумент командной строки, поэтому это "virtualenv".

Это происходит потому, что ряд системных вызовов exec() (если вам интересно, обратитесь к man-странице) позволяют передавать массив аргументов командной строки, когда вы заменяете текущий процесс дочерним процессом. Оболочка вызывает некоторый вариант exec() и анализирует вашу командную строку, чтобы определить, какой массив аргументов командной строки передать как argv .

Так как stat не знает, является ли предоставленный вами файл обычным файлом, символической ссылкой, жесткой ссылкой, исполняемым файлом или нет, каталогом и т.д., Он не ищет $PATH чтобы найти его. Переданный аргумент обрабатывается как указание, в частности, ${PWD}/virtualenv где ${PWD} расширяется до текущего рабочего каталога во время вызова программы stat . Это называется относительный путь .

Почти все команды, которые принимают относительные пути для имен файлов в качестве аргумента, не будут искать $PATH , хотя некоторые команды могут это делать, например, bash или ssh если вы скажете им выполнить команду в среде дочерней оболочки. Ничто не мешает какой-либо произвольной команде просматривать любую конкретную переменную среды для файла, который вы предоставляете, но это поведение конкретного приложения. Не было бы никакого смысла искать в $PATH относительные пути, потому что $PATH только для исполняемых файлов.

3

PATH необходим и к нему обращаются, когда вы пытаетесь что-то выполнить.

В отличие от Windows, в Unix вам всегда нужно указывать исполняемые файлы с путем. ./foo.bin или /usr/bin/foo.bin . Однако для простоты существует эта вещь, называемая PATH . Так что достаточно набрать foo.bin потому что /usr/bin находится на вашем пути.

И если вы когда - нибудь задумывались , какой файл будет решена с помощью foo.bin which там , чтобы сказать вам: /usr/bin/foo.bin

Поэтому любой другой инструмент UNIX, принимающий в качестве аргументов как исполняемые, так и неисполняемые файлы, вероятно, не будет обращаться к PATH .

1

Оболочка обращается к PATH при выполнении программ, чтобы найти программу для выполнения. Когда это параметр (например, для команд which или stat в вашем примере), оболочка просто передает его программе, которую она нашла, и программа решает, что с ней делать.

Команда which встроена в bash, и она принимает аргумент и обращается к пути оболочки, чтобы выяснить, что будет делать оболочка для ее выполнения. Большинство других программ (включая большинство других программ, встроенных в bash), таких как stat в вашем примере, просто используют путь и пытаются найти его в текущем каталоге файловой системы.

Таким образом, выполнение команд (и тому подобное, which пытаются выяснить, какие команды нужно выполнить) - единственные вещи, которые используют PATH.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .