web-dev-qa-db-fra.com

Pourquoi avez-vous besoin de ./ (point-slash) avant l'exécutable ou le nom du script pour l'exécuter en bash?

Lors de l'exécution de scripts dans bash, je dois écrire ./ au début:

$ ./manage.py syncdb

Si je ne le fais pas, je reçois un message d'erreur:

$ manage.py syncdb
-bash: manage.py: command not found

Quelle est la raison pour ça? Je pensais que . était un alias pour le dossier actuel et que ces deux appels devraient donc être équivalents.

Je ne comprends pas non plus pourquoi je n'ai pas besoin de ./ pour exécuter des applications, telles que:

user:/home/user$ cd /usr/bin
user:/usr/bin$ git

(qui tourne sans ./)

264
Dan Abramov

Parce que sous Unix, le répertoire actuel n’est généralement pas dans $PATH.

Lorsque vous tapez une commande, le shell consulte une liste de répertoires, comme indiqué par la variable PATH. Le répertoire actuel ne figure pas dans cette liste.

La raison pour laquelle le répertoire en cours ne figure pas sur cette liste est la sécurité.

Disons que vous êtes root et allez dans le répertoire d'un autre utilisateur et tapez sl au lieu de ls. Si le répertoire en cours est dans PATH, le shell tentera d'exécuter le programme sl dans ce répertoire (car il n'y a pas d'autre programme sl.). Ce programme sl pourrait être malveillant.

Cela fonctionne avec ./ car POSIX spécifie qu'un nom de commande contenant un / sera utilisé directement comme nom de fichier, en supprimant une recherche dans $PATH. Vous auriez pu utiliser le chemin complet pour le même effet exact, mais ./ est plus court et plus facile à écrire.

EDIT

Cette partie sl n'était qu'un exemple. Les répertoires dans PATH font l'objet d'une recherche séquentielle et, lorsqu'une correspondance est trouvée, ce programme est exécuté. Donc, selon l'apparence de PATH, taper une commande normale peut être suffisant ou non pour exécuter le programme dans le répertoire en cours.

288
cnicutar

Lorsque bash interprète la ligne de commande, il recherche les commandes aux emplacements décrits dans la variable d'environnement $PATH. Pour le voir tapez:

echo $PATH

Vous aurez des chemins séparés par des deux points. Comme vous le verrez, le chemin actuel . n'est généralement pas dans $PATH. Donc, Bash ne peut pas trouver votre commande si elle se trouve dans le répertoire en cours. Vous pouvez le changer en ayant:

PATH=$PATH:.

Cette ligne ajoute le répertoire actuel dans $PATH pour que vous puissiez faire:

manage.py syncdb

C'est pas recommandé car il a un problème de sécurité, en plus vous pouvez avoir des comportements bizarres, comme . varie en fonction du répertoire dans lequel vous vous trouvez :)

Éviter:

PATH=.:$PATH

Comme vous pouvez "masquer" une commande standard et ouvrir la porte à une atteinte à la sécurité :)

Juste mes deux cents.

49
neuro

Votre script, lorsqu'il est dans votre répertoire de base, ne sera pas trouvé lorsque le shell examinera la variable d'environnement $PATH pour trouver votre script.

Le ./ indique 'cherchez dans mon répertoire le script en cours plutôt que de consulter tous les répertoires spécifiés dans $PATH'.

40
mdm

Lorsque vous incluez le '.' vous donnez essentiellement le "chemin d'accès complet" au script bash exécutable, votre shell n'a donc pas besoin de vérifier votre variable PATH. Sans le '.' votre shell va chercher dans votre variable PATH (ce que vous pouvez voir en exécutant echo $PATH] pour voir si la commande que vous avez tapée habite dans l’un des dossiers de votre PATH. Si ce n’est pas le cas (comme dans le cas de la commande manage. py) indique que le fichier ne peut pas être trouvé. Il est considéré comme une mauvaise pratique d’inclure le répertoire en cours sur votre PATH, ce qui s’explique raisonnablement ici: http://www.faqs.org/faqs/unix -faq/faq/part2/section-13.html

5
Mark Drago

Sur * nix, contrairement à Windows, le répertoire en cours ne se trouve généralement pas dans votre variable $PATH. Le répertoire en cours n'est donc pas recherché lors de l'exécution des commandes. Vous n'avez pas besoin de ./ pour exécuter des applications car ces applications are dans votre $ PATH; très probablement, ils sont dans /bin ou /usr/bin.

2
Anomie

Cette question a déjà des réponses géniales, mais je voulais ajouter que si votre exécutable est sur le chemin, et que vous obtenez des sorties très différentes lorsque vous exécutez

./executable

à ceux que vous obtenez si vous courez

executable

(supposons que vous rencontriez des messages d’erreur avec l’un et pas avec l’autre), le problème pourrait alors être que vous avez deux versions différentes de l’exécutable sur votre ordinateur: l’une sur le chemin, l’autre non.

Vérifiez cela en exécutant

quel exécutable

et

whereis executable

Cela corrigeait mes problèmes ... J'avais trois versions de l'exécutable, dont une seule était compilée correctement pour l'environnement.

1
KR_Henninger

Lorsque le script n'est pas dans le chemin, vous devez le faire. Pour plus d'informations, lisez http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_01.html

0
Gayan Hewa