Quando o $ PATH é consultado no uso do shell?

1

Às vezes, preciso especificar um caminho completo, porque aparentemente o $ PATH não é consultado:

####            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: -
$ 

Por que preciso usar which virtualenv se estiver no meu caminho?

    
por Dmitry Minkovsky 29.11.2012 / 15:48

3 respostas

5

$PATH só é consultado quando executa comandos. Quando o shell precisa procurar um comando para executar, ele consulta $PATH e percorre a lista de diretórios em $PATH e escolhe o primeiro arquivo executável (com um bit de execução apropriado definido nas permissões) que corresponde ao nome fornecido, e executa isso.

Quando você executar stat virtualenv , estará passando virtualenv como um argumento para o programa stat . Supondo que stat seja escrito em C, ele verá virtualenv como um argumento no método principal do programa:

int main(int argc, char** argv)

O argv contém dois elementos: o índice 0 é o comando usado para invocar o próprio programa, portanto, é "stat". O índice 1 é o primeiro argumento de linha de comando, por isso é "virtualenv".

Isso acontece porque a série exec() de chamadas do sistema (procure a página de manual se você estiver curioso) permite que você passe uma matriz de argumentos de linha de comando ao substituir o processo atual por um processo filho. O shell chama uma variante de exec() e analisa sua linha de comando para determinar qual array de argumentos da linha de comando deve passar como argv .

Como stat não sabe se o arquivo que você forneceu é um arquivo normal, um link simbólico, um hardlink, executável ou não, diretório, etc., ele não pesquisa $PATH para encontrá-lo. Ele trata o argumento transmitido como especificando, especificamente, ${PWD}/virtualenv em que ${PWD} é expandido para o diretório de trabalho atual no momento em que o programa stat foi chamado. Isso é chamado de caminho relativo .

Quase todos os comandos que aceitam caminhos relativos para nomes de arquivos como um argumento não pesquisam $PATH , embora alguns comandos possam fazê-lo, como bash ou ssh se você disser -los para executar um comando no ambiente de shell filho. Não há nada que impeça qualquer comando arbitrário de examinar qualquer variável de ambiente específica para o arquivo fornecido, mas é um comportamento específico do aplicativo. Não faria qualquer sentido procurar $PATH para caminhos relativos, porque $PATH é apenas para arquivos executáveis.

    
por 29.11.2012 / 15:56
3

O PATH é necessário e consultado quando você está tentando executar algo.

Ao contrário do Windows, no Unix você sempre precisa especificar arquivos executáveis com um caminho. ./foo.bin ou /usr/bin/foo.bin . No entanto, para simplificar, existe essa coisa chamada PATH . Portanto, basta digitar foo.bin porque /usr/bin está em seu caminho.

E se você já se perguntou que qual arquivo está resolvido via foo.bin , which está lá para dizer: /usr/bin/foo.bin .

Portanto, todas as outras ferramentas UNIX que aceitam arquivos executáveis e não-executáveis como argumentos provavelmente não irão consultar PATH .

    
por 29.11.2012 / 15:58
1

O PATH é consultado pelo shell ao executar programas para encontrar o programa a ser executado. Quando é um parâmetro (como os comandos which ou stat no seu exemplo), o shell apenas o passa para o programa que encontrou e o programa decide o que fazer com ele.

O comando which está embutido no bash, e pega o argumento e consulta o caminho do shell para descobrir o que o shell faria para executá-lo. A maioria dos outros programas (incluindo a maioria dos outros programas construídos no bash), como stat em seu exemplo, apenas usa o caminho e tenta encontrá-lo no diretório atual no sistema de arquivos.

Então, executar comandos (e coisas como which que estão tentando descobrir quais comandos executar) são as únicas coisas que usam o PATH.

    
por 29.11.2012 / 15:56