./ contre . pour exécuter des programmes sous le terminal

13

J'aurais besoin de précisions sur la façon dont nous exécutons les exécutables sous le terminal. Cela peut être une question boiteuse mais quelle est la différence entre exécuter un exécutable avec ./an_executableet . an_executable(supposons que nous sommes dans le répertoire où se trouve an_executable)

Je sais déjà que le premier fait que le shell recherche un_exécutable dans le répertoire courant ( .), mais pourquoi n'est-il pas /nécessaire après l' .utilisation de la dernière version?

Merci d'avance.

zipzap
la source

Réponses:

22

La . executablesyntaxe ne fonctionne pas avec n'importe quel exécutable (ou le fait-il?). Au lieu de cela, c'est un alias pour le bash sourceintégré. Donc, la différence concerne principalement les scripts bash, et la vérité est que ce sont des choses complètement différentes :)

./executabledemande d'exécuter l'exécutable "normalement". ./est une référence relative au chemin actuel. Cela évite que le shell (bash) essaie de localiser l'exécutable dans un répertoire de son $PATH(ce qu'il ferait si vous ne spécifiiez pas du tout un chemin avec la commande). La raison pour laquelle vous ne pouvez pas simplement faire executableest une question de sécurité; imaginez que vous décompressez une archive que vous avez téléchargée et qu'elle contient une version malveillante de ls. S'il s'exécutait directement à partir de votre répertoire actuel, vous exécuteriez cette version sans vous en rendre compte.

D'autre part, . executabledit "source d'un fichier nommé executable". Étant donné que vous nommez directement le fichier et qu'il ne doit vraiment pas être un exécutable, la restriction de sécurité pour $ PATH ne s'applique pas. Le sourcing "exécutera" (ou semblera exécuter) uniquement les scripts shell. Ce qu'il fait c'est:

   source filename [arguments]
          Read and execute commands from filename  in  the  current  shell
          environment  and return the exit status of the last command exe‐
          cuted from filename.

Alors ... Quelle est vraiment la différence entre l'exécution et le sourcing? En supposant le même script shell, son exécution ( ./script) générera un nouveau shell, exécutera le script à l'intérieur de ce shell, et lorsque le script se fermera, fermez ce shell et revenez au shell parent. En effet, il lancera un nouveau bashprocessus pour exécuter le script).

( . script) obligera le shell actuel à lire les commandes du fichier comme si elles étaient saisies dans la ligne de commande. Il n'y a pas de nouvel obus apparu.

Un moyen très simple de voir comment cela se comporte est d'écrire un script qui ne contient que exit. Si vous ./scriptle faites , rien ne semble se produire, car un nouveau processus de shell est démarré, la exitcommande quitte ce nouveau shell et votre shell actuel n'est pas affecté.

Si vous . script, votre terminal actuel se fermera, car la exitcommande s'exécute dans le shell actuel. C'est donc équivalent à taper exitsur l'invite de commande.

roadmr
la source
En effet, j'avais affaire à un script shell lorsque j'ai remarqué ce comportement. Merci beaucoup, c'est la réponse dont j'avais besoin. :)
zipzap
une autre question posée (si cela ne vous dérange pas): si mon script contient juste quelques messages simples avec echo, et que je l'exécute avec ./script, alors pourquoi suis-je capable de voir les messages dans le shell parent si le sous-shell se ferme dès la fin de l'exécution?
zipzap
2
Parce que même si le sous-shell est un processus distinct , il utilise le même terminal que le shell appelant. C'est similaire à la façon dont vous pouvez toujours voir la lssortie: vous tapez la commande, elle s'exécute, affiche la sortie puis se termine, mais la sortie reste dans le terminal.
roadmr
2
Ne confondez pas shell avec terminal; ce sont des choses différentes. Ouvrez un terminal et l'invite de commande est donnée par un bashshell s'exécutant à l'intérieur. Si vous tapez bash, vous exécuterez un autre shell; au premier shell, c'est juste un programme à exécuter. Si vous tapez exit, vous fermerez le dernier shell que vous avez démarré mais vous serez toujours dans le premier shell (celui à partir duquel vous avez démarré le terminal). Encore une fois, tout cela se produit dans le même terminal.
roadmr
1
@DavidZ Je l'ai mentionné :) "Le sourcing" exécutera "(ou semblera exécuter) les scripts shell."
roadmr