Comment Unix recherche-t-il les fichiers exécutables?

47

Quand un fichier est exécuté, comment Unix le recherche-t-il? S'il y a plusieurs fichiers exécutables dans PATH avec le même nom, lequel est préféré? Le répertoire actuel est-il inclus dans la recherche lorsqu'un fichier est exécuté?

Supposons qu'il y ait un fichier avec nom executable.shdans le répertoire en cours. Cela fonctionnerait-il s'il est exécuté $ executedet .ne fait pas partie de la PATH?

Leonid
la source
mentionner la which <executable>commande sera utile dans ce fil.
Comptable À partir du

Réponses:

45

Le $ PATH est recherché du début à la fin, le premier exécutable correspondant étant exécuté. Les répertoires au début de $ PATH ont donc priorité sur ceux qui viennent plus tard. Les exécutables du répertoire actuel (.) Ne sont exécutés que si. est dans $ PATH (ce qui n'est généralement pas le cas ). Il n'y a pas d'inclusion implicite du répertoire en cours dans le chemin de recherche.

coneslayer
la source
C'est bizarre que mon $ PATH n'en contienne pas ., mais il semble qu'il faudrait d'abord chercher dans le répertoire courant, avant de vérifier les répertoires définis dans $ PATH lui-même.
Eric Wang
19

Pour les fichiers du répertoire en cours, vous voudrez les faire précéder ./afin que la commande devienne ./executable.sh. Vous ne devriez jamais avoir .dans votre PATH car cela pose un risque de sécurité, entre autres problèmes.

Les répertoires qui viennent en premier dans le PATH et qui sont recherchés en premier.

L' ordre général de recherche est le suivant si je me souviens bien:

  • alias

  • fonctions exportées

  • commandes shell intégrées

  • scripts et fichiers binaires dans votre PATH

John T
la source
7
J'ajouterais le hachage - rappelez-vous que bash (et peut-être d'autres coquilles) conservent un hachage de commandes récemment utilisées pour faciliter leur recherche. Parfois, vous devez vider le cache (utiliser hash -r) si vous modifiez votre chemin PATH ou l'emplacement du programme.
Rich Homolka
3
+1 pour l'ordre de recherche. Ce serait bien si vous pouviez vous souvenir de la source d'information :)
twan163
8

Bien que certains autres y aient bien répondu, j'aimerais ajouter quelques réflexions:

1) PATH est uniquement consulté si l'exécutable appelé ne contient aucun élément de chemin. certaines commandes seraient recherchées dans $ PATH, ./somecommandou bien /usr/bin/somecommand, ../../bin/somecommandutilisez simplement les règles de répertoires, pas PATH

S'il y a plusieurs fichiers exécutables dans PATH avec le même nom, lequel est préféré?

Il s'arrête au premier trouvé, lisant $ PATH de gauche à droite.

Le répertoire courant est-il inclus dans la recherche lorsque le fichier est exécuté?

Si le répertoire en cours est dans PATH, la recherche est effectuée. Rappelez-vous qu'un répertoire vide dans PATH inclut le répertoire actuel. Par exemple, PATH =: / usr / bin (vide) PATH = / usr / bin: (fin vide) et PATH = / usr / bin :: / bin (milieu vide) inclura tous les répertoires de travail actuels.

Supposons qu’un fichier portant le nom executable.sh se trouve dans un répertoire en cours. Cela fonctionnerait-il s'il est exécuté $ executé et. ne fait pas partie du PATH?

Il ne le trouverait jamais en cherchant PATH. Si le répertoire en cours n'est pas dans PATH, il ne le trouvera pas par une recherche dans PATH.

Cela dit (et désolé d'ajouter de la confusion) s'il y avait un alias ou une fonction qui exécutait la commande, elle serait exécutée. Ou si votre shell avait un cache d'emplacement et que l'exécutable était dans le cache, il pourrait le trouver. Donc, il ne le trouvera jamais dans PATH, mais il peut être géré par d'autres moyens.

Rich Homolka
la source
Merci pour la cachenote, cela me rend presque fou que l'ancien exécutable de /usr/bin/soit toujours invoqué, pas le nouveau /usr/local/bin, mais il est à gauche dans la $PATHcaisse où je me suis déconnecté puis reconnecté.
Comptable À partir du
1
@theaccountant in bash, vous pouvez utiliser 'hash -r' pour effacer le cache shell
Rich Homolka
4

Pour voir quel est votre chemin echo $PATH, tapez simplement , ou printenv PATH.

Ensuite, vous connaîtrez l'ordre de recherche. Si vous avez plusieurs fichiers portant le même nom, exécutez simplement lequel _____ à voir.

Ex.

système #> qui grep

/ usr / bin / grep

un moyen pratique de trouver des fichiers qui fonctionnent comme votre cible est d’utiliser apropos:

à propos de grep

bzgrep (1) - recherche éventuellement dans des fichiers compressés bzip2 une expression régulière

egrep (1) - imprime des lignes correspondant à un motif

fgrep (1) - imprime des lignes correspondant à un motif

grep (1) - imprime des lignes correspondant à un motif

etc...

mbb
la source
2
Oh oui - j'ai oublié la fonction whereis pour trouver TOUTES les instances d'un fichier:> whereis grep
mbb
grep: / bin / grep / usr / bin / grep /usr/share/man/man1/grep.1.gz
mbb
whereisutilise une liste codée en dur d'emplacement, pas $PATH.
Grawity
@grawity Pourriez-vous développer?
WinEunuuchs2Unix
-2

@ coneslayer- L'ordre de recherche par défaut de l'exécutable est le chemin actuel, les commandes intégrées, puis le $ PATH. Donc, si une fonction nommée exécutable existe déjà dans le pwd, c'est exécuté. Si ce n'est pas le cas, la recherche de priorité recherche les commandes intégrées du shell, puis $ PATH

proc
la source
Si vous parliez de la coquille Thompson, de la coquille Mashey ou de quelque autre résidu fossilisé d'il y a 40 ans, vous avez peut-être raison. Mais pas de shell Unix actuel courant dans le répertoire courant automatiquement.
Scott
@Scott Ainsi, le chemin de recherche par défaut d'une commande est d'abord intégré, puis $ PATH et recherche dans le CWD uniquement si je donne ./? Ai-je raison?
Proc
Eh bien, les alias, les fonctions et les fonctions intégrées. Ensuite, si vous spécifiez un chemin avec la commande (y compris ./), il ne recherche que ce répertoire; sinon, il cherche $PATH.
Scott