Quelle est la différence entre exécuter un exécutable uniquement par son nom et ajouter un point / barre oblique devant lui?

13

Voici la sortie de la ls -allcommande:

-rwxr----- 1 subhrcho dba  3600 Nov 13 17:26 jdev
-rw-r----- 1 subhrcho dba  1566 Nov 13 17:26 jdev-Darwin.conf
-rw-r----- 1 subhrcho dba   347 Mar  6  2009 jdev-debug.boot
-rw-r----- 1 subhrcho dba   821 Nov 13 17:26 jdev-logging-debug.conf
-rw-r----- 1 subhrcho dba   584 Nov 13 17:26 jdev-logging.conf
-rw-r----- 1 subhrcho dba  4717 Jul 31 16:09 jdev.boot
-rw-r----- 1 subhrcho dba 12877 Nov 13 17:26 jdev.common
-rw-r----- 1 subhrcho dba  5047 Dec  6 01:43 jdev.conf
-rwxr-x--- 1 subhrcho dba 28160 Nov 13 16:28 jdev.exe
-rwxr-x--- 1 subhrcho dba 28672 Nov 13 16:28 jdev64.exe
-rwxr-x--- 1 subhrcho dba 28672 Nov 13 16:28 jdev64W.exe
-rwxr-x--- 1 subhrcho dba 28160 Nov 13 16:28 jdevW.exe

Maintenant, quand je viens de l'exécuter, jdevil exécute une version différente d' Oracle JDveloper que lorsque je l'exécute en tant que ./jdev..Pourquoi est-ce le cas?

Geek
la source

Réponses:

20

Lorsque vous exécutez un fichier exécutable (ou plutôt dans le monde unix / linux - un fichier avec des droits / drapeau exécutable) comme ceci:

$ ./jdev

vous marquez ensuite .que vous souhaitez exécuter un fichier dans votre répertoire de travail (répertoire dans lequel vous vous trouvez actuellement) qui est nommé jdevet dispose de droits exécutables pour l'utilisateur qui le lance (vous devez noter qu'il peut toujours être un lien vers autre fichier, vous pouvez le vérifier en tapant ls -l jdevdans le terminal)

(voir les autorisations de fichiers sous linux / unix )

Lorsque vous l'exécutez en tant que

$ jdev

alors très probablement, il est jdevinstallé quelque part sur le système et vous l'avez $PATH(par exemple /usr/bin/ou /bin/ou /usr/local/bin/)

Comme l'a dit Peter : vous pouvez utiliser whichpour pointer l'exécutable qui est lancé avec une commande particulière, par exemple:

$ which find
/usr/bin/find
Patryk
la source
1
Ce n'est pas non plus que l' whichutilitaire peut vous dire quel exécutable sera utilisé si aucun chemin n'est donné.
peterph
@peterph Modifié ma réponse.
Patryk
7
Il est préférable de typevérifier ce qui est lancé par une commande particulière. Cause whichvous montrera juste un binaire quelque part dans le $ PATH, mais il peut être aliasé à absolument un autre binaire.
précipiter le
@rush I a juste essayé et ça ne fonctionne pas comme vous le dites: [~] $which zsoelim /usr/bin/zsoelim [~] $ type zsoelim zsoelim is /usr/bin/zsoelim. Tandis quezsoelim -> soelim
Patryk
2
@Patryk Je pense que rush signifiait les alias / fonctions du shell, qui whichn'a aucune chance de trouver, car c'est un binaire autonome qui n'a pas accès à l'environnement shell en cours d'exécution (j'entends par là les alias et les fonctions, pas seulement les variables d'environnement , dont certains sont hérités).
peterph
8

Si vous appelez alors une commande sans barre oblique dans son nom dans un shell, elle est recherchée dans les alias, fonctions et dans la liste des chemins fournis dans la $PATHvariable d'environnement. (notez que vous pouvez avoir le répertoire de travail actuel (spécifié comme .ou la chaîne vide) ou tout répertoire relatif $PATH, mais ce n'est pas recommandé pour des raisons de sécurité).

S'il y a une barre oblique dans le nom, cela ne se produit pas, le nom est pris comme chemin pour exécuter la commande (bien que certains shells comme zshpermettent aux alias ou aux fonctions d'avoir des barres obliques dans leur nom qui auraient alors priorité).

Donc, si vous voulez exécuter une commande appelée fooqui se trouve dans le répertoire de travail actuel, vous devez trouver un nom qui contient une barre oblique. ./fooest le plus évident. Vous pouvez également utiliser le chemin complet, ou ../dir/foo...

Pour savoir ce que le shell exécuterait, utilisez la typecommande. N'utilisez pas la whichcommande qui ne fait généralement pas ce que vous pensez qu'elle est et qui est un héritage cshdont il vaut mieux laisser seul.

Stéphane Chazelas
la source
Pourquoi pas "qui" mais "type"?
Geek
@Geek, C'est une FAQ ici, voir unix.stackexchange.com/search?q=[which]+type
Stéphane Chazelas
avez-vous fourni le bon lien?
Geek
C'est un résultat de recherche sur ce site pour prouver qu'il s'agit d'une question fréquemment posée. De nombreuses réponses à ces questions vous diront pourquoi ne pas utiliser which. Voir par exemple unix.stackexchange.com/questions/16693/…
Stéphane Chazelas
2

Je recommande d'utiliser le «où» intégré de Zsh (mieux que «lequel») pour voir comment et dans quel ordre les alias, les shell intégrés ou quoi que ce soit d'autre seront trouvés afin de $ PATH ;-)

Voici un exemple pour mieux comprendre les choses, comment elles sont choisies:

[ 0:04:08 ] afsin@s15426859:~ % pwd
/home/afsin
[ 0:04:30 ] afsin@s15426859:~ % which who
/usr/bin/who
[ 0:04:47 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
[ 0:05:27 ] afsin@s15426859:~ % echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/afsin/bin
[ 0:05:31 ] afsin@s15426859:~ % touch who
[ 0:05:40 ] afsin@s15426859:~ % chmod +x who
[ 0:05:47 ] afsin@s15426859:~ % ls -al who
-rwxr-xr-x 1 afsin afsin 0 23. Jan 00:05 who
[ 0:05:50 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
[ 0:05:55 ] afsin@s15426859:~ % export PATH=$PATH:.
[ 0:06:09 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
./who
[ 0:06:14 ] afsin@s15426859:~ % alias who=who
[ 0:06:19 ] afsin@s15426859:~ % where who
who: aliased to who
/usr/bin/who
/usr/bin/X11/who
./who
[ 0:06:22 ] afsin@s15426859:~ % which who
who: aliased to who
[ 0:06:27 ] afsin@s15426859:~ %
Afsin Toparlak
la source
1

Bien que cela dépende probablement de votre shell, la règle est généralement:

  • Si vous fournissez un chemin, relatif ou absolu, ce chemin est utilisé. ./jdevest un chemin relatif, car .représente le répertoire courant (en fait, ls -all .vous donnerait la même chose que ls -all). Si vous le faites /usr/bin/tool/, vous utilisez un chemin absolu. Dans ces cas, le fichier pointé est exécuté.

  • Si vous ne fournissez pas de chemin, mais simplement un nom, les répertoires dans $PATHsont recherchés pour l'outil que vous essayez d'exécuter.

Si vous avez un fichier dans le répertoire en cours avec le même nom qu'un fichier dans certains des répertoires $PATHet que vous l'exécutez en ajoutant ./son nom, vous exécuterez effectivement un fichier différent.

Un autre problème est peut-être que vous vous attendiez jdevà exécuter l'exécutable dans le répertoire en cours. À moins que vous ayez changé $PATHpour l'inclure ., ce n'est pas quelque chose que vous devriez attendre du tout ...

... et ce n'est toujours pas une bonne idée de l'inclure .ici, si vous le faites, veuillez au moins le mettre à la fin, afin que le reste $PATHsoit toujours recherché en premier - imaginez simplement que vous êtes sur un répertoire réseau partagé et quelqu'un décide d'y mettre un binaire diabolique car ls, si cela $PATHcommence ., un simple ls -lahsuffira pour attaquer votre système.

njsg
la source
Votre terminologie prête à confusion. jdevseul est également un chemin relatif. La règle est la suivante: s'il ne contient pas de barre oblique, il est recherché dans les alias, les fonctions et $PATH, sinon, il est recherché directement dans le système de fichiers (bien que certains shells autorisent les alias ou les fonctions avec / dans leur nom, ce qui prendrait alors priorité).
Stéphane Chazelas