3. Notions de base : le shell, les processus, l'environnement

En guise d'hasardeuse métaphore, il serait possible de comparer le shell à un chef d'orchestre règlant l'ensemble des musiciens (les commandes) pour jouer une partition commune... à ceci près que le chef d'un orchestre ne joue pas réellement (si ce n'est de la baguette) alors que le shell, non seulement commande la symphonie Unix, mais y participe activement via ses commandes internes.

3.1. Les commandes internes / externes

Un certain nombre de commandes acceptées par le shell sont immédiatement exécutées au sein de son propre processus : ce sont les commandes internes du shell. Ces commandes ont général pour but de modifier l'environnement courant (ex. cd, pwd, export, etc...) ou encore sont suffisamment simples pour être implémentées au sein du shell (ex. type).

A contrario, une commande externe est implémentée par un fichier exécutable présent au sein du système de fichiers. (ex. ls, cp, type, etc...)

Note

A l'instar de la commande pwd, certaines commandes sont implémentées à la fois en tant que commande interne ou externe : comment savoir laquelle va être exécutée ?

Le principe est simple : la priorité est donnée à l'implémentation interne (et ce pour la simple raison de performances) ! Si vous tenez absolument à invoquer la commande externe, il faudra alors l'invoquer par son chemin d'accès complet (ex. /bin/pwd).

La différence en termes de performances entre les deux types de commandes est notable. En effet, comme il a été dit plus haut, une commande interne est directement exécutée par le shell courant, dans son propre processus ; alors qu'une commande externe sera systématiquement exécutée par un shell fils du shell courant, créé via un appel système fork(...) qui aura dû dupliquer l'environnement du processus père et recopié l'ensemble de ses descripteurs.

3.2. L'environnement utilisateur

Lorsqu'un shell est lancé, un certain nombre de variables sont initialisées, soit de façon automatique par le shell lui-même (valeurs par défaut), soit par des mécanismes automatiques et paramétrables dans des fichiers texte (fichiers de profil ou de ressources) : c'est l'ensemble des valeurs de ces variables qui est appelé environnement.

Ces variables sont simplement déclarée en utilisant la commande interne declare (qui peut également être omise) ; leur destruction pouvant alors s'opérer grace à la commande unset.

Exemple :

td_scripts$ declare TOTO='un texte' est équivalent à td_scripts$ TOTO='un texte' pour initialiser la variable TOTO avec la valeur (une chaine de caractères) 'un texte'.

L'accès à la valeur d'une variable particulière, s'obtient simplement en préfixant à son nom du caractère $.

Exemple :

td_scripts$ echo $PATH affiche la valeur de la variable PATH (les chemins de recherche des exécutables).

Pour afficher l'ensemble des variables de l'environnement courant, le shell dispose d'une commande interne : set

Il est également possible via la commande env de modifier l'environnement temporairement, afin d'exécuter une commande. Sans aucun paramètre ni argument ( ou alors simplement -i), la commande env [-i] affiche un environnement initial, c'est à dire ne comportant que les variables exportées par le shel courant.

L'environnement est donc controlé via un certain nombre de fichier de paramétrage, certains sont utilisés par l'ensemble du système, d'autres sont particuliers à chaque utilisateur. Il s'agit de scripts-shell destinés à être lus par le shell lors de son démarrage ; et il faut de plus différencier deux types de comportements selon que le shell qui se lance soit un shell de connexion (c'est à dire le shell lancé immadiatement après l'identification de l'utilisateur), soit un shell de session (shell lancé interactivement en cours de session).

3.2.1. Fichiers utilisés par le shell de connexion :

Le premier fichier lu est un fichier système nommé /etc/profile qui contient des paramétrages communs à tous les utilisateurs du système. Ensuite, le shell va chercher dans le répertoire de l'utilisateur le fichier .profile (du moins les shells sh et ksh) ; ou, dans l'ordre, les fichiers .bash_profile, .bash_login et .profile (shell bash).

Ces fichiers permettent donc d'affiner, globalement et pour chacun des utilisateurs, le contenu des variables d'environnement (prompt, chemin d''exécution, etc...) ou les paramètres système (umask, définition du terminal, etc...).

Note

Ne pas définir dans ces fichiers des options du shell ou des alias : ces entités ne se transmettent par définition pas entre processus, et donc seront purement et simplement ignorées par les shells enfants !

3.2.2. Fichiers utilisés par un shell de session :

Les shells ksh et bash (à la différence de sh) voient leur comportement modifié en cas de lancement post-session (ils prennent aussi alors la dénomination de "shells interactifs") : outre l'héritage des variables exportées du shell de session, ils vont lire un fichier supplémentaire, nommé, pour le shell bash ~/.bashrc ; et dépendant de la variable ENV pour le shell ksh (celle-ci est généralement initialisée à la valeur .kshrc).

Note

Ces fichiers de configuration ne sont lus par le shell que lors de son démarrage. Aussi, en cas de modification en cours de session, pour en tester le résultat, il est inutile de singer l'utilisateur type de Microsoft Windows™ (i.e. redémarrer le système) : la commande interne . (ex. . ~/.bashrc) est la solution !

3.2.3. Transmission de l'environnement entre processus :

Lorsqu'une commande est lancée, celle -ci est généralement exécutée dans un shell (processus) fils via un appel système fork(...) lequel va dupliquer les descripteurs ouverts et l'environnement du processus père : en fait d'environnement, seules les variables exportées sont réellement transmises, les autres étant purement et simplement ignorées !

La simple manipulation suivante permet d'en cerner le fonctionnement :

td_scripts$ TOTO='Une chaine de caractères.'

td_scripts$ echo $TOTO affiche : td_scripts$ Une chaine de caractères.

td_scripts$ bash

td_scripts$ echo $TOTO affiche : td_scripts$ RIEN ! la variable TOTO n'est pas initialisée dans ce nouvel environnement.

Pour l'exporter, il suffit d'utiliser la commande interne du shell export après avoir déclaré la variable : td_scripts$ export TOTO ; ou lors de sa déclaration : td_scripts$ export TOTO='ma chaine de caractères'

Note

L'environnement du processus fils est dupliqué (c'est à dire copié !), donc si dans le shell fils, la variable TOTO est modifiée ou détruite (par exemple via la commandeunset TOTO), l'environnement du père n'est nullement affectée, et une fois de retour dans ce dernier, TOTO aura toujours sa valeur initiale.

3.3. Les options du shell

Les shells permettent de paramétrer certaines de leurs fonctionnalités qui peuvent être activées ou désactivées via l'utilisation des options -o et +o de la commande interne set

Exemple :

td_scripts$ set +o noclobber indique au shell d'émettre un avertissement en cas d'existence d'un fichier cible lors d'une redirection simple en sortie.

Pour voir l'ensemble de ces fonctionnalités, se reporter à la page de man du shell utilisé...