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 a.out
? Y a-t-il une solution pour cela?
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 a.out
? Y a-t-il une solution pour cela?
Réponses:
Lorsque vous tapez le nom d'un programme tel que a.out
le système cherche 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 command not found
erreur.
Le préfixe de la commande ./
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 relatif ou absolu, tel que:
../
signifie dans le répertoire parent, par exemple, ../hello
recherchez hello dans le répertoire parent.
./Debug/hello
: "cherche hello
dans le sous-répertoire Debug de mon répertoire actuel."
ou /bin/ls
: "chercher 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. pas dans le chemin par défaut? sur 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.
.
à votre PATH
(comme les 2 autres réponses suggèrent actuellement) en raison du risque de sécurité mentionné dans cette réponse.
.
ici, vous pouvez utiliser un chemin complet ou par rapport à un exemple exécutable /home/user/foo/a.out
ou./build/a.out
.
c’est spécial parce que cela signifie "mon répertoire actuel", ainsi que tout répertoire dans lequel l’utilisateur se trouve lui-même avec les privilèges de lecture et d’exécution. Ceci est potentiellement plus dangereux que l’ajout d’un chemin qualifié complet.
.
détient pas un statut particulier, il est juste un chemin qui pourrait tout aussi bien commencer /
et ./blah
fonctionnerait aussi bien avec cat
ou grep
comme une invite bash.
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 au lieu de la commande intégrée. Ce serait un problème de sécurité si rien d’autre.
En demandant ./
à être utilisé devant, le shell sait que vous souhaitez exécuter l'application avec le nom indiqué et non avec une commande intégrée portant ce nom.
./
exécute des fichiers qui ne sont pas dans votre $PATH
fichier, 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 que 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 réel ls
. La variable PATH définit également l'ordre de recherche:
exec
appel système (méthode spéciale du noyau permettant de démarrer les programmes), le système recherche le fichier en parcourant chacun des répertoires de votre 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 :
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 - type 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 que vous le déplacez /usr/local/sbin
, il est exécuté à la place du fichier approprié cat
, qui réside dans /bin
. Vous pouvez trouver où sont vos fichiers en utilisant type cat
et whereis cat
.
gcc
, ce qui définit automatiquement le bit d'exécution.
./
avant d'exécuter un programme?Dans le terminal, chaque fois que vous tapez le nom d'une application, par exemple gedit
, 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 PATH
. 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 que le terminal aller rechercher, si vous tapez juste gedit
, nautilus
ou a.out
. Comme vous pouvez le constater, le chemin de votre a.out
programme n’est pas là. Lorsque vous le faites ./a.out
, vous dites au terminal "regardez dans le répertoire actuel, puis exécutez a.out
-le et ne le regardez pas PATH
."
Si vous ne voulez pas taper à ./
chaque fois, vous devez ajouter a.out
le répertoire dans $PATH
. Dans les instructions suivantes, je suppose que le chemin d'accès a.out
est /path/to/programs/
, mais vous devez le changer pour votre chemin réel.
Ajoutez simplement la ligne suivante à la fin du fichier ~/.pam_environment
:
PATH DEFAULT=${PATH}:/path/to/programs
Déconnectez-vous et reconnectez-vous. Vous pourrez maintenant exécuter a.out
sans ./
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.
Remarque: remplacez
userName
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é bin
sous votre répertoire de base et à ajouter des liens symboliques (raccourcis) sous ce dossier. Voici comment:
mkdir /home/userName/bin
bin
dans votre répertoire de base.ln -s /path/to/programs/a.out /home/userName/bin
a.out
programme sous bin
.Déconnectez-vous et reconnectez-vous. Vous pourrez maintenant exécuter a.out
sans ./
répertoire.
Maintenant, chaque fois que vous avez un autre programme n'importe où 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 alors l'exécuter sans vous ./
aussi.
Remarque: grâce au commentaire de @ Joe , lorsque vous effectuez des sauvegardes, les liens symboliques doivent être traités de manière spécifique. Par défaut, ils
rsync
ne sont pas traités du tout. Ainsi, lors de la restauration, ils ne sont pas là.
Comme George l'a souligné dans sa réponse, cela vous aide à noter que vous exécutez un fichier dans le répertoire de travail actuel ( 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 afin que, lorsque je le ferais, a.out
il regarde 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 êtes sur un répertoire de réseau extraterrestre ou quelque chose du genre, et qu'un fichier exécutable malveillant appelé ls
existe là-bas, alors avoir .
dans votre chemin est une très mauvaise idée. Non pas que vous rencontriez ce problème très souvent, simplement en disant.
.
à $PATH
. Idée très dangereuse.
En plus d’autres réponses, voici la partie essentielle de man bash
ce qui explique bien:
Exécution de commande Après qu'une commande ait été scindée en mots, s'il en résulte une simple commande et une liste optionnelle d'arguments, les actions suivantes sont pris. Si le nom de la commande ne contient pas de barre oblique, le shell tente de localiser il. S'il existe une fonction shell portant ce nom, cette fonction est invoqué comme décrit ci-dessus dans FONCTIONS. Si le nom ne correspond pas à un fonction, le shell le recherche dans la liste des commandes intégrées au shell. Si une correspondance est trouvée, cette construction est invoquée. Si le nom n’est ni une fonction shell, ni une fonction intégrée, et ne contient pas slash, bash cherche dans chaque élément du PATH un répertoire contenant taining un fichier exécutable de ce nom.
Un './' prend tout son sens lorsque vous exécutez un programme connu pour vous et spécifique, par exemple le vôtre. 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.
$ 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 du 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.
./
élimine la recherche inutile d'un chemin. ./
forcer à rechercher dans le répertoire actuel seulement. Si nous ne donnons pas ./
alors il va chercher divers chemin d' accès défini dans le système comme /usr/bin
, /usr/sbin/
, etc.
"./" 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 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 êtes paresseux pour "cd" pour vous rendre à l'emplacement du fichier.
C'est très simple et a de nombreuses utilisations.
/usr/bin
. Par exemple, Python 2.7, Python 2.6 est installé mais / usr / bin / python -> python2.7 / usr / local / bin / python -> python2.6Si vous êtes sur le chemin /usr/local/bin
et que vous exécutez Python, celui-ci sera toujours exécuté. La spécification .
prendra l'exécutable du dossier actuel.
.
- représente toujours exécuter depuis le répertoire en cours. Et ..
toujours signifie s'exécute à partir du répertoire précédent.