web-dev-qa-db-fra.com

Que se passe-t-il lorsque nous tapissons une simple commande sur shell?

J'ai une question simple concernant l'exécution d'une simple commande. Selon ma compréhension, lorsque nous tapissons une commande telle que ls dans une coque interactive,

  1. Shell interprète la commande.
  2. Shell crée un processus enfant et exécute la commande sur le processus d'enfant.
  3. Shell attend la fin du processus de l'enfant.

Si ma compréhension est correcte, une simple commande que nous avons saisie à l'invite de Shell est exécutée sur un processus enfant et le résultat du commandement n'affecte pas l'environnement actuel de la coque.

Si oui, qu'en est-il des commandes intégrées comme cd? Si cd est exécuté sur un processus enfant et ne peut affecter l'environnement de Shell actuel, comment le répertoire de travail de la coque actuel peut-il être modifié?

35
MS.Kim

Le Shell est juste un programme, bien qu'il joue un rôle important dans le système. Bash, et je suppose la plupart des autres coquilles communes, sont mis en œuvre en C. Les deux plus importants natif C appels système qui sont utilisés dans la création de sous-processus sont fork() et exec(). Ces fonctions sont généralement mises en œuvre dans les langues de niveau supérieur aussi, y compris Shell.

  1. fork()

    " Fourchette " crée une copie double du processus appelant comme son enfant. C'est ainsi pratiquement tous les processus du système, à l'exception de la première ( init ) commencent: que des copies du processus qui les a commencé. langue Shell n'a pas vraiment une fonction fork, mais il inclut la syntaxe pour générer, sous-couches qui sont la même chose.

  2. exec()

    Il n'y a pas en fait un exec() appel en C, mais il se réfère familièrement à un groupe de fonctions connexes; vous pouvez voir la liste avec man 3 exec, qui commence habituellement:

    La famille exec () des fonctions remplacer l'image du processus en cours avec une nouvelle image de processus ...

    Et c'est exactement ce qu'il fait: remplace définissant les parties de la pile de mémoire de processus en cours avec des choses nouvelles chargées à partir d'un fichier exécutable (par exemple, /usr/bin/ls). Ceci est la raison pour laquelle fork() est nécessaire d'abord dans la création d'un nouveau processus - sinon, le processus d'appel cesse d'être ce qu'il était et devient autre chose à la place; aucun nouveau processus réellement créé.

Cela peut paraître au premier abord comme une manière absurde et inefficace de faire des choses: pourquoi ne pas avoir juste une commande qui crée un nouveau processus à partir de zéro? En fait, ce ne serait probablement pas aussi efficace pour plusieurs raisons:

  • La "copie" produit par fork() est un peu une abstraction, car le noyau utilise un copy-on-write système; tout ce qui doit vraiment être créé est une carte de mémoire virtuelle. Si la copie puis appelle immédiatement exec(), la plupart des données qui auraient été copiés si elle avait été modifiée par l'activité du processus n'a jamais réellement à copier/créés parce que le processus ne fait rien nécessitant son utilisation.

  • Divers aspects importants du processus de l'enfant (par exemple, son environnement) ne doivent pas être dupliqué individuellement ou ensemble basé sur une analyse complexe du contexte, etc. Ils sont juste supposés être la même que celle du processus d'appel, et c'est le système assez intuitif que nous connaissons.

Pour une discussion détaillée exactement ce que cela signifie de " copier l'environnement " au processus de l'enfant donné naissance, voir ma réponse ici .

Si oui, que sur les commandes intégrées comme cd?

Ceux-ci sont, encore une fois, tout mis en œuvre en C. chdir(), comme fork() et exec(), fait partie des extensions de la plate-forme Unix à C standard et ce qui est à la base de Shell commande cd. A partir de man 2 chdir:

chdir () modifie le répertoire de travail courant du processus appelant dans le répertoire spécifié dans le chemin.

Cela ne nécessite pas un sous-processus - elle affecte l'appelant. Le Shell est une exécution interactive interprète , ce qui signifie qu'il exécute le code écrit dans la langue Shell que vous alimentez les commandes. Il ne surtout pas besoin d'exécuter un nouveau processus pour le faire, il le fait en lui-même.

34
goldilocks

Si oui, qu'en est-il des commandes intégrées comme CD? Si CD est exécuté sur un processus enfant

Ici, réside la faille de votre logique. cd, étant une coquille intégrée, est interprété spécialement par la coquille et "exécuté" en cours. Vous pouvez utiliser la commande type pour savoir si une commande est intégrée ou non.

8
strugee