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 ./
)
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.
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.
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
'.
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
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
.
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.
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