web-dev-qa-db-fra.com

Pourquoi utilisons-nous "./" (barre oblique) pour exécuter un fichier sous Linux / UNIX?

Pourquoi utilisons-nous ./filename pour exécuter un fichier sous linux?

Pourquoi ne pas simplement le saisir comme les autres commandes gcc, ls etc ...

89
Renjith G

Sous Linux, UNIX et les systèmes d'exploitation associés, . désigne le répertoire courant. Étant donné que vous souhaitez exécuter un fichier dans votre répertoire actuel et que ce répertoire ne se trouve pas dans votre $PATH, vous avez besoin du ./ bit pour indiquer au shell où se trouve l'exécutable. Donc, ./foo signifie exécuter l'exécutable appelé foo qui se trouve dans ce répertoire.

Vous pouvez utiliser type ou which pour obtenir le chemin complet de toutes les commandes trouvées dans votre $PATH.

80
badp

La réponse littérale est celle que d'autres ont donnée: parce que le répertoire courant n'est pas dans votre $PATH.

Mais pourquoi? Bref, c'est pour la sécurité. Si vous recherchez dans le répertoire personnel de quelqu'un d'autre (ou/tmp) et tapez simplement gcc ou ls, vous voulez savoir que vous utilisez le vrai, pas une version malveillante de votre ami de farceur a écrit ce qui efface tous vos fichiers. Un autre exemple serait test ou [, ce qui pourrait remplacer ces commandes dans les scripts Shell, si votre Shell n'en a pas comme intégrées.

Ayant . car l'entrée last de votre chemin est un peu plus sûre, mais il existe d'autres attaques qui en font usage. Une solution simple consiste à exploiter les fautes de frappe courantes, comme sl ou ls-l. Ou, trouvez une commande courante qui n'est pas installée sur ce système - vim, par exemple, car les administrateurs système ont une probabilité supérieure à la moyenne de taper cela.

103
mattdm

Si vous voulez dire, pourquoi avez-vous besoin de ./ au début - c'est parce que (contrairement à Windows), le répertoire actuel ne fait pas partie de votre chemin par défaut. Si vous exécutez:

$ ls

votre Shell recherche ls dans les répertoires de votre variable d'environnement PATH (echo $PATH pour le voir) et exécute le premier exécutable appelé ls qu'il trouve. Si vous tapez:

$ a.out

le Shell fera de même - mais il ne trouvera probablement pas d'exécutable appelé a.out. Vous devez indiquer au shell où se trouve a.out - s'il se trouve dans le répertoire courant (.), Le chemin est ./a.out.

Si vous demandez pourquoi il s'appelle "a.out", c'est juste le nom du fichier de sortie par défaut pour gcc. Vous pouvez le changer avec la ligne de commande -o arg. Par exemple:

$ gcc test.c -o test
$ ./test
45
Simon Whitaker

Vous pouvez essayer d'ajouter :. à votre variable $ PATH.

Essayez ALT + F2 et tapez: gksudo gedit /etc/environment si vous utilisez Linux/GTK (c'est ce que vous avez si vous utilisez Ubuntu).

CEPENDANT, je vous déconseille fortement de le faire. C'est mauvais mauvais mauvais et mauvais.

Vous savez, ce genre de choses fonctionne comme ça depuis 1970. Il y a une raison pour laquelle le répertoire actuel n'est pas inclus dans $ PATH.

. est le répertoire courant

.something serait un fichier caché (Tapez "ALT +" pour les faire apparaître dans Nautilus, ou essayez "ls -la ".

./someProgram.sh est ce que vous tapez pour exécuter un exécutable someProgram.sh dans le répertoire courant.

.somethingElse signifierait que vous avez un exécutable caché dans le répertoire courant, ce qui est une mauvaise idée.

4
tiktak

La règle la plus complète est en fait: si une barre oblique / Se trouve dans le chemin, ne recherchez pas PATH

Avant d'entrer dans la logique, vous devez d'abord savoir ce fait: exécuter l'un des:

bin/someprog

ou:

/bin/someprog

ou:

cd bin
./myexec

exécutez bin/someprog sans rechercher la variable PATH pour la même raison: tous les bin/someprog, /bin/someprog et ./someprog ont une barre oblique / En eux.

someprog seul n'a pas de barre oblique /, et recherche donc uniquement dans PATH.

POSIX 7 spécifie cette règle à: http: //pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01

Justification de la règle / POSIX PATH

Supposons que l'exécution:

someprog

rechercherait:

  • par rapport à CWD en premier
  • par rapport à PATH après

Ensuite, si vous vouliez exécuter /bin/someprog À partir de votre distribution, et vous avez fait:

someprog

cela fonctionnerait parfois, mais d'autres échoueraient, car vous pourriez être dans un répertoire qui contient un autre programme someprog non lié.

Par conséquent, vous apprendrez bientôt que ce n'est pas fiable et vous finirez toujours par utiliser des chemins absolus lorsque vous souhaitez utiliser PATH, ce qui ira à l'encontre de l'objectif de PATH.

C'est aussi pourquoi avoir des chemins relatifs dans votre PATH est une très mauvaise idée. Je suis vous regarde, node_modules/bin .

À l'inverse, supposons que l'exécution:

./someprog

Rechercherait:

  • par rapport à PATH en premier
  • par rapport à CWD après

Ensuite, si vous venez de télécharger un script someprog à partir d'un référentiel git et que vous vouliez l'exécuter à partir de CWD, vous ne seriez jamais sûr que c'est le programme réel qui s'exécuterait, car peut-être que votre distribution a un:

/bin/someprog

qui est dans votre CHEMIN à partir d'un paquet que vous avez installé après avoir trop bu après Noël l'année dernière.

Par conséquent, encore une fois, vous seriez obligé de toujours exécuter des scripts locaux relatifs à CWD avec des chemins d'accès complets pour savoir ce que vous exécutez:

"$(pwd)/someprog"

ce qui serait également très ennuyeux.

Une autre règle que vous pourriez être tenté de proposer serait:

les chemins relatifs utilisent uniquement PATH, les chemins absolus uniquement CWD

mais encore une fois, cela oblige les utilisateurs à toujours utiliser des chemins absolus pour les scripts non-PATH avec "$(pwd)/someprog".

La règle de recherche de chemin / Offre une solution simple à retenir au problème de:

  • barre oblique: n'utilisez pas PATH
  • pas de barre oblique: utilisez uniquement PATH

ce qui rend super facile de toujours savoir ce que vous exécutez, en s'appuyant sur le fait que les fichiers dans le répertoire en cours peuvent être exprimés soit ./somefile ou somefile, et donc cela donne une signification particulière à l'un d'eux.

Parfois, c'est un peu ennuyeux que vous ne puissiez pas rechercher some/prog Par rapport à PATH, mais je ne vois pas de solution plus saine à cela.