Pourquoi utilisons-nous ./filename
pour exécuter un fichier sous linux?
Pourquoi ne pas simplement le saisir comme les autres commandes gcc
, ls
etc ...
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
.
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.
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
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.
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:
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:
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:
PATH
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.