$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.