web-dev-qa-db-fra.com

Pourquoi dois-je taper `. /` Avant d'exécuter un programme dans le répertoire en cours?

Lors de l'exécution d'un programme C, a.out, à l'aide du terminal Ubuntu, pourquoi dois-je toujours taper ./ avant a.out au lieu d'écrire simplement a.out? Y a-t-il une solution pour cela?

89
Prashant Chikhalkar

Lorsque vous tapez le nom d'un programme tel que a.out, le système recherche le fichier dans votre PATH. Sur mon système, PATH est défini sur

/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Le vôtre est probablement similaire. Pour vérifier, entrez echo $PATH dans un terminal.

Le système examine ces répertoires dans l'ordre indiqué et, s'il ne trouve pas, le programme génère une erreur command not found.

Le préfixe précédant la commande avec ./ indique effectivement "oubliez PATH, je veux que vous regardiez uniquement dans le répertoire en cours".

De la même manière, vous pouvez demander au système de rechercher uniquement un autre emplacement spécifique en ajoutant à la commande un préfixe avec un chemin relatif ou absolu, tel que:

../ signifie dans le répertoire parent, par exemple ../hello, recherchez hello dans le répertoire parent.

./Debug/hello: "recherchez hello dans le sous-répertoire Debug de mon répertoire actuel."

ou /bin/ls: "recherchez ls dans le répertoire /bin"

Par défaut, le répertoire en cours ne se trouve pas dans le chemin car il est considéré comme un risque pour la sécurité. Voir Pourquoi est-ce que .n'est pas dans le chemin par défaut? sur le superutilisateur pour pourquoi.

Il est possible d'ajouter le répertoire actuel à votre PATH, mais pour les raisons données dans la question liée, je ne le recommanderais pas.

115
Warren Hill

La raison en est simple.

Supposons que vous ayez une commande portant le même nom qu'une application dans le répertoire en cours. Ensuite, exécuter la commande dans le shell invoquerait votre application à la place de la commande intégrée. Ce serait un problème de sécurité si rien d’autre.

En exigeant que ./ soit utilisé devant, Shell sait que vous souhaitez exécuter l'application avec le nom indiqué et non avec une commande intégrée portant ce nom.

24
Nathan Osman

./ exécute les fichiers qui ne sont pas dans votre $PATH, mais exécute plutôt le fichier dans le répertoire actuel (ou un autre via ./home/stefano/script.sh). Maintenant, PATH est une variable d’environnement qui contient tous les endroits où bash peut rechercher des programmes exécutables sans avoir le chemin complet (absolu).

Cette séparation est nécessaire pour éviter d’exécuter le mauvais fichier. C'est à dire. si vous avez un fichier appelé ls dans votre répertoire personnel, le fait qu'il ne soit pas dans votre PATH empêchera bash de le confondre avec le vrai ls. La variable PATH définit également l'ordre de recherche:

  • Lorsque vous exécutez une commande ou qu'un programme essaie de créer un syscall exec (une méthode spéciale du noyau, le mode de démarrage des programmes), le système recherche le fichier en parcourant chacun des répertoires de votre chemin PATH. Une fois le programme trouvé, même s'il se trouve dans plusieurs annuaires, la recherche est interrompue et le premier trouvé est exécuté.

Pour exécuter un fichier, vous devez définir le bit exécutable dans les autorisations:

  • Puisque vous êtes déjà en ligne de commande, vous pouvez simplement taper chmod +x finename.

  • Ou vous pouvez définir les autorisations en faisant un clic droit sur le fichier et en sélectionnant Propriétés:

    alt text

Vous pouvez maintenant copier le fichier dans n’importe quel des répertoires de PATH pour voir quels sont ceux-ci - et ils sont définis par utilisateur - tapez echo $PATH.

stefano@3000-G530:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Si vous créez un fichier exécutable, cat, et le déplacez vers /usr/local/sbin, il est exécuté à la place du cat approprié, qui réside dans /bin. Vous pouvez trouver où sont vos fichiers en utilisant type cat et whereis cat.

16
Stefano Palazzo

Pourquoi devez-vous taper ./ avant d'exécuter un programme?

Dans le terminal, chaque fois que vous tapez le nom d'une application, par exemple geditname__, le terminal va rechercher des répertoires (prédéfinis) contenant des applications (les fichiers binaires des applications). Les noms de ces répertoires sont contenus dans une variable appelée PATHname__. Vous pouvez voir le contenu de cette variable en exécutant echo $PATH. Voir ces répertoires séparés par :? Ce sont les répertoires dans lesquels le terminal va chercher, si vous tapez simplement geditname__, nautilusou a.out. Comme vous pouvez le constater, le chemin de votre programme a.out n’y figure pas. Quand vous faites ./a.out, vous dites au terminal "regardez dans le répertoire actuel, exécutez a.out et ne regardez pas dans PATHname__.

Solution 1

Si vous ne voulez pas taper ./ à chaque fois, vous devez ajouter le répertoire de a.out dans $PATH. Dans les instructions suivantes, je suppose que le chemin d'accès à a.out est /path/to/programs/, mais vous devez le remplacer par votre chemin d'accès réel.

  1. Ajoutez simplement la ligne suivante à la fin du fichier ~/.pam_environment:

    PATH DEFAULT=${PATH}:/path/to/programs
    

    Source: Variables d'environnement persistantes

  2. Déconnectez-vous et reconnectez-vous. Vous pourrez désormais exécuter a.out sans ./ à partir de n'importe quel répertoire.

Si vous avez d'autres programmes dans d'autres répertoires, vous pouvez simplement les ajouter à la ligne ci-dessus. Cependant, je vous conseillerais par exemple d'avoir un répertoire appelé "mes programmes" et de placer tous vos programmes sous celui-ci.

Solution 2

Remarque: remplacez userNamepar votre nom d'utilisateur Ubuntu actuel.

Et si vous avez d'autres programmes à exécuter? Et ils sont tous dans des dossiers différents? Une solution "plus organisée" consisterait à créer un dossier appelé bindans votre répertoire de base et à ajouter des liens symboliques (raccourcis) dans ce dossier. Voici comment:

  1. mkdir /home/userName/bin

    • Cela créera le dossier bindans votre répertoire de base.
  2. ln -s /path/to/programs/a.out /home/userName/bin

    • Cela créera un "lien symbolique" (en gros, un raccourci) de votre programme a.out sous binname__.
  3. Déconnectez-vous et reconnectez-vous. Vous pourrez désormais exécuter a.out sans ./ à partir de n'importe quel répertoire.

Maintenant, chaque fois que vous avez un autre programme ailleurs, disons le programme b.in sur votre bureau, tout ce que vous avez à faire est: ln -s /home/userName/Desktop/b.in /home/userName/bin et vous pourrez ensuite l'exécuter sans également ./.

Remarque: grâce à commentaire de @ Joe , lorsque vous effectuez des sauvegardes, les liens symboliques doivent être traités de manière spécifique. Par défaut, rsyncne les traite pas du tout. Par conséquent, lors de la restauration, ils ne sont pas présents.

11
Alaa Ali

Comme George l'a souligné dans sa réponse, cela vous aide à noter que votre en cours d'exécution un fichier du répertoire de travail en cours (pwd).

Je me souviens d’avoir posé cette question à mon aîné il y a longtemps. Il a dit que je devrais ajouter . à mon chemin pour que, lorsque je le ferais, a.out apparaisse dans le répertoire en cours et l’exécute. Dans ce cas, je n'ai pas à faire ./a.out.

Mais, personnellement, je le déconseille. Cela ne m’est jamais arrivé, mais si vous vous trouvez sur un répertoire réseau étranger ou quelque chose d’autre et qu’un fichier exécutable malveillant appelé ls existe déjà, il est très mauvais d’avoir . dans votre chemin. Non pas que vous rencontriez ce problème très souvent, simplement en disant.

1
Shrikant Sharat

./ élimine la recherche inutile d'un chemin. ./ force à rechercher uniquement dans le répertoire en cours. Si nous ne donnons pas ./, il recherchera différents chemins définis dans le système, tels que /usr/bin, /usr/sbin/, etc.

0
user175959

Un './' a du sens lorsque vous exécutez un programme qui est connu pour vous et spécifique, par exemple. votre propre. Ce programme doit être présent dans votre répertoire actuel. Un './' n'a aucun sens lorsque vous exécutez une commande standard située quelque part dans $ PATH. Une commande "quelle commande exécuter" vous indique où se trouve la commande à exécuter dans le $ PATH.

0
user7346

"./" signifie que vous voulez exécuter un fichier dans le répertoire courant, c'est un raccourci pour taper le chemin complet, par exemple:

[root@server ~]#/path/to/file/file.pl

est identique à:

[root@server file]#./file.pl

dans l'exemple précédent, vous avez parcouru le répertoire et ses sous-répertoires jusqu'à l'emplacement du fichier et avez utilisé "./" pour exécuter le fichier dans le répertoire en cours.

celui qui le précède "[racine @ serveur ~] #/chemin/vers/fichier/fichier.pl" exécutera également le fichier si vous vous attardez à "cd" pour vous rendre à l'emplacement du fichier.

0
Khaled Moustafa
$ gcc hello.c -o /path/to/someplace/hello

produira un exécutable à un endroit. Si cet emplacement est sur votre chemin, vous pourrez exécuter le fichier. Vous pouvez créer un script si vous souhaitez créer un libellé pour l'action "compilez ce code source à l'aide de gcc et placez un exécutable à un emplacement situé sur votre chemin".

Je vous suggérerais de créer un nouveau répertoire appelé "testbin" ou quelque chose du genre et de le placer sur votre chemin pour garder propres vos répertoires de chemins existants.

0
Jon Kiparsky