Como o Unix procura por arquivos executáveis?

47

Quando um arquivo é executado, como o Unix o procura? Se houver vários arquivos executáveis ​​no PATH com o mesmo nome, qual é o preferido? O diretório atual está incluído na pesquisa quando um arquivo é executado?

Suponha que exista um arquivo com nome executable.shno diretório atual. Isso funcionaria se for executado $ executede .não fizer parte do PATH?

Leonid
fonte
which <executable>comando de menção será útil neste segmento.
Accountant em 18/04

Respostas:

45

O $ PATH é pesquisado do começo ao fim, com o primeiro executável correspondente sendo executado. Portanto, os diretórios no início de $ PATH têm precedência sobre os que vêm mais tarde. Os executáveis ​​no diretório atual (.) São executados apenas se. está em $ PATH (o que geralmente não é ). Não há inclusão implícita do diretório atual no caminho de pesquisa.

coneslayer
fonte
É estranho que meu $ PATH não contenha ., mas parece que ele pesquisaria primeiro o diretório atual antes de verificar os diretórios definidos no próprio $ PATH.
Eric Wang
19

Para arquivos no diretório atual, você deverá precedê-los ./, para que o comando se torne ./executable.sh. Você nunca deve ter .no seu PATH, pois isso representa um risco à segurança, entre outros problemas.

Diretórios que vêm primeiro no PATH e pesquisados ​​primeiro.

A ordem geral da pesquisa é assim se bem me lembro:

  • aliases

  • funções exportadas

  • comandos shell integrados

  • scripts e binários em seu PATH

John T
fonte
7
Eu adicionaria o hash - lembre-se de que o bash (e talvez outros shells) mantém um hash de comandos usados ​​recentemente para facilitar a localização. Às vezes, você precisa limpar o cache (usando hash -r) se alterar o PATH ou os locais do programa.
Rich Homolka
3
+1 para a ordem de pesquisa. Seria bom se você pudesse se lembrar a fonte de informação :)
twan163
8

Embora isso tenha sido bem respondido por alguns outros, gostaria de acrescentar alguns pensamentos:

1) PATH é consultado apenas se o executável invocado não tiver elementos de caminho. algum comando seria procurado em $ PATH, ./somecommandou /usr/bin/somecommand, ou ../../bin/somecommandapenas use regras de diretório, não PATH

Se houver vários arquivos executáveis ​​no PATH com o mesmo nome, qual é o preferido?

Ele para no primeiro local encontrado, lendo $ PATH da esquerda para a direita.

O diretório atual está incluído na pesquisa quando o arquivo é executado?

Se o diretório atual estiver em PATH, ele será pesquisado. Lembre-se de que um diretório vazio no PATH inclui o diretório atual. por exemplo, PATH =: / usr / bin (vazio à esquerda) PATH = / usr / bin: (à direita vazio) e PATH = / usr / bin :: / bin (vazio no meio) incluirão efetivamente o diretório de trabalho atual.

Suponha que exista um arquivo com o nome executable.sh em um diretório atual. Isso funcionaria se for executado $ execute e. não faz parte do PATH?

Nunca o encontraria pesquisando PATH. Se o diretório atual não estiver no PATH, ele não será encontrado por uma pesquisa PATH.

Dito isto (e lamento acrescentar confusão) se houvesse um alias ou função que executasse o comando, ele seria executado. Ou, se o seu shell tiver um cache de localização e o executável estiver no cache, ele poderá ser encontrado. Portanto, nunca o encontrará no PATH, mas pode ser executado por outros meios.

Rich Homolka
fonte
Obrigado pela cacheobservação, quase me enlouquece que o antigo executável /usr/bin/ainda não seja chamado pelo novo /usr/local/bin, mas fica à esquerda $PATHaté eu sair e entrar novamente.
Accountant em 18/04
1
@theaccountant no bash você pode fazer 'hash -r' para limpar o cache do shell
Rich Homolka
4

Para ver qual é o seu caminho atualmente, basta digitar echo $PATH, ou printenv PATH.

Então você saberá a ordem da pesquisa. Se você tiver vários arquivos com o mesmo nome, execute o que ____ para ver.

Ex.

sistema #> qual grep

/ usr / bin / grep

uma maneira legal de encontrar arquivos que funcionem como seu destino é usar o propósito:

apropos grep

bzgrep (1) - pesquisa possivelmente uma expressão regular em arquivos compactados do bzip2

egrep (1) - imprime linhas correspondentes a um padrão

fgrep (1) - imprime linhas correspondentes a um padrão

grep (1) - imprime linhas correspondentes a um padrão

e assim por diante...

mbb
fonte
2
Oh yeah - Eu esqueci o whereis função para encontrar todas as ocorrências de um arquivo:> whereis grep
mbb
grep: / bin / grep / usr / bin / grep /usr/share/man/man1/grep.1.gz
mbb
whereisusa uma lista codificada de locais, não $PATH.
grawity
@rawrawity Você poderia expandir isso?
WinEunuuchs2Unix
-2

@ coneslayer - A ordem padrão para encontrar o executável é o caminho atual, comandos internos e, em seguida, o $ PATH. Portanto, se uma função denominada executável já existir no pwd, isso será executado. Caso contrário, a precedência procurará comandos internos do shell e, em seguida, $ PATH

proc
fonte
Se você estava falando sobre a casca de Thompson, a casca de Mashey ou alguma outra recuperação fossilizada de 40 anos atrás, pode estar certo. Mas nenhum shell Unix atual e mainstream pesquisa automaticamente o diretório atual.
Scott
@ Scott Portanto, o caminho de pesquisa padrão de um comando é primeiro incorporado e, em seguida, $ PATH e pesquisa o CWD somente se eu fornecer ./? Estou certo?
proc
Bem, aliases, funções e builtins. Então, se você especificar um caminho com o comando (inclusive ./), ele pesquisará apenas esse diretório; caso contrário, ele pesquisa $PATH.
Scott