2010-09-08 3 views
4

J'ai essayé de comprendre comment un shell sait dans quel répertoire vous êtes actuellement. Je sais qu'il y a une variable d'environnement $PWD mais quand j'essaye de le changer manuellement, ça change ce que mon shell montre à l'invite mais les commandes comme ls et cd ne sont pas affectés.Comment le shell sait-il dans quel répertoire il se trouve?

cd est une commande shell interne afin que je puisse le comprendre peut utiliser les informations stockées dans la mémoire de la coque, mais ls est externe et en cours d'exécution encore ls sans rien me donner tout ce que le répertoire que j'étais à l'origine dans peu importe ce que je fais à $PWD.

Répondre

9

Le shell définit cette variable, mais stocke la connaissance en interne (c'est pourquoi vous ne pouvez pas faire cd un programme externe, il doit être un built-in). L'invite du shell est composée juste avant son affichage à chaque fois, et vous l'avez spécifiée en utilisant $PWD dans le vôtre, donc le shell lit cela.

Rappelez-vous: le shell est juste un programme, comme n'importe quel autre programme. Il peut - et fait - stocker des choses dans des variables.


Comme AndiDog et John point de sortie des systèmes unix-like (à savoir, y compris Linux) maintient en fait le répertoire de travail pour chaque processus par un ensemble d'appels système. Le stockage est encore processus local, cependant.

+0

c'est exactement la bonne réponse. – Ian

1

Vous (OP) lancez ls via votre shell de commande, et tout processus que vous lancez, le shell se lance dans le contexte de son répertoire de travail actuel. Ainsi, chaque processus que vous lancez possède sa propre variable $PWD (d'une certaine manière).

+1

Il y a un argument rarement utilisé pour main (int argc, char ** argv, char ** envp), c'était le troisième paramètre, que l'environnement a été copié en main par l'os en commençant le processus, ceci est abandonné maintenant comme la plupart des systèmes le font automatiquement ... – t0mm13b

12

Chaque processus possède son propre répertoire de travail courant que le système Linux suit. C'est l'une des informations que le système d'exploitation gère pour chaque processus. Il y a un appel système getcwd() qui récupère ce répertoire.

La variable d'environnement $PWD correspond à getcwd() lors de la dernière vérification de l'environnement, mais sa modification ne modifie pas réellement le répertoire en cours. Pour ce faire, le shell devrait appeler chdir() quand $PWD changements, ce qu'il ne fait pas.

Ceci est également la raison pour laquelle cd doit être un shell intégré. Lorsque vous exécutez un sous-processus que le processus enfant obtient son propre répertoire de travail, si cd était un exécutable alors ses appels à chdir() seraient inutiles car cela ne changerait pas le répertoire de travail de son parent. Cela ne ferait que changer son propre répertoire de travail (éphémère). Par conséquent, cd est un shell intégré pour éviter le lancement d'un sous-processus.

+0

préfet! merci –

+6

Un amusement à part: selon * A Quarter Century d'UNIX * (je pense), dans * vraiment * vieux Unix, 'chdir' était en fait * un processus externe. C'est parce qu'il n'y avait pas de 'wait', le shell ne faisait qu'exécuter les programmes qu'il exécutait, et le shell était reexcité à la sortie. Cela signifiait que '/ bin/chdir' pouvait simplement' chdir() 'et ensuite re-'exec' le shell, qui hériterait du nouveau CWD. :) – hobbs

+0

Oups, mes backticks sont hors de contrôle et il est trop tard pour les éditer;) – hobbs

3

Le noyau Linux stocke le répertoire courant de chaque processus. Vous pouvez le rechercher dans le système de fichiers/proc (par exemple, "/ proc/1/cwd" pour le processus d'initialisation).

Le répertoire en cours peut être modifié avec le syscall chdir et récupéré avec getcwd.

1

Le répertoire en cours est une propriété d'un programme (processus) en cours d'exécution qui est hérité par les processus créés par ce processus. La modification du répertoire actuel s'effectue via un appel du système d'exploitation. Le shell mappe l'opération cd à cet appel système. Lorsque vous écrivez un programme externe comme ls, ce programme hérite du répertoire en cours.

La variable $PWD est la façon dont le shell affiche le répertoire courant pour vous permettre de l'utiliser comme variable si vous en avez besoin. Le changer n'a pas d'effet dans le répertoire actuel du shell lui-même.