Utilisation du shell
Les différents shells
Le shell est à la fois un interpréteur de commandes et un langage de programmation permettant l’écriture de procédures utilitaires (scripts). Par ce deuxième aspect, il s’avère être un outil de travail important pour l’administrateur système.
Le shell est un programme extérieur au noyau. Il réalise l’interprétation d’un certain nombre de caractères spéciaux avant l’appel proprement dit des commandes. Cette caractéristique est essentielle et son intérêt est déjà apparu, dans le chapitre précédent, au niveau de mécanismes tels que les redirections et le pipeline.
Lors de la création d’un compte utilisateur, l’administrateur système associe un shell de connexion à cet utilisateur. Les principaux shells disponibles sont les suivants :
Bourne shell (sh ou bsh)
Il s’agit du shell le plus ancien, créé par Steve Bourne. On ne l’utilise quasiment plus en interactif à cause de son manque de confort (absence d’alias, impossibilité de rappel de commandes...). Le Bourne shell correspond cependant à un gros patrimoine de scripts, de par son aspect standard au niveau de la programmation.
C shell (csh) et Tenex C shell (tcsh)
Le C shell est issu des versions Unix Berkeley. Il a été écrit...
Variables et environnement
1. Variables
Exceptions faites de certaines variables spéciales utilisées principalement en programmation, le nom d’une variable peut être constitué de lettres, de chiffres et du caractère _ (tiret bas). Il ne peut pas commencer par un chiffre.
Une variable contient une chaîne de caractères quelconque.
Le caractère = (signe égal) est le symbole d’affectation de variable et permet la création de celle-ci.
Le caractère $ permet de désigner la valeur d’une variable. Si la variable n’existe pas, nous obtiendrons la chaîne vide.
La commande unset permet d’annuler la définition d’une variable, ce qui est rarement utile.
Exemples
$ var=toto
$ echo $var
toto
$ unset var
$ echo $var
$
Dans certaines constructions, la désignation de la valeur d’une variable doit se faire à l’aide de la notation ${ } qui permet de bien préciser le nom de la variable par rapport à une chaîne littérale.
Exemple
$ a=pa
$ b=ul
$ echo $a$b
paul
$ echo $a$bette
pa
$ echo $a${b}ette
paulette
$
Les accolades sont nécessaires dans la notation ${b}ette pour isoler le nom de la variable b par rapport à la chaîne littérale ette.
2. Environnement
L’environnement désigne l’ensemble des variables qui seront transmises au processus fils lors de sa création via le mécanisme du fork (voir chapitre Processus et mécanismes). Au niveau du shell, une variable est placée dans l’environnement par la commande export. Pour désigner l’environnement, on utilise d’ailleurs quelquefois le terme de variables exportées.
Une variable non exportée n’est pas connue dans le processus fils. S’il s’agit d’une variable prédéfinie du shell, elle reprend sa valeur par défaut. Les éventuelles modifications, dans le processus fils, des variables de l’environnement s’opèrent sur des copies locales et n’altèrent donc pas les variables du processus parent. Il y a donc un mécanisme d’héritage du parent vers le fils mais il n’y a jamais de remontée du fils vers le parent.
La commande...
Caractères spéciaux
Comme nous avons déjà eu l’occasion de le souligner, le shell interprète un certain nombre de caractères avant l’appel proprement dit des commandes.
Ce principe d’interprétation préliminaire de caractères spéciaux permet de faciliter l’utilisation des commandes, sans changement, dans un nombre varié de contextes (redirections, pipeline, arrière-plan...).
La liste d’arguments transmis aux commandes pourra également comporter des caractères génériques (ou jokers) pour désigner de façon abrégée des noms de fichiers. Ces caractères seront également traités par le shell afin de fournir aux commandes une liste de paramètres déjà résolue. Ce principe favorise grandement l’activité de programmation.
Tous ces aspects cumulés s’inscrivent parfaitement dans la démarche boîte à outils voulue par les concepteurs du système.
1. Rappel des caractères spéciaux déjà évoqués
< |
Redirection de l’entrée standard. |
> et >> |
Redirections de la sortie standard (écrasement ou ajout). |
2> et 2>> |
Redirections de l’erreur standard (écrasement ou ajout). |
; |
Processus séquentiels. |
| |
Mécanisme du pipeline. |
& |
Mode arrière-plan. |
( ) |
Groupement de commandes. |
= |
Affectation de variable. |
$ |
Contenu de variable. |
2. Désignations abrégées de noms de fichiers (jokers, caractères génériques)
Ces caractères spéciaux, souvent baptisés jokers ou caractères génériques, prennent un sens pour désigner des noms de fichiers existants. Si ces caractères ne sont pas résolus (aucun fichier ne leur correspond), ils sont, malgré tout, transmis tels quels à la commande.
Les caractères génériques sont les suivants :
*
Le caractère * remplace n’importe quelle suite de caractères (même vide) dans le nom de fichier. Utilisé seul, il désigne tous les noms de fichiers du répertoire courant, excepté ceux qui commencent par . (point).
?
Le caractère ? indique la présence d’un caractère quelconque...
Fonctionnalités interactives
1. Alias
Le mécanisme d’alias permet de définir des abrégés pour des commandes souvent utilisées. Il permet aussi de surcharger des commandes, c’est-à-dire de forcer l’utilisation de certaines options.
La commande alias permet de définir un alias. Invoquée sans argument, elle donne la liste des définitions existantes.
Exemples
$ ls -l
total 6
-rw-r--r-- 1 michel michel 0 Sep 26 17:38 fic1
-rw-r--r-- 1 michel michel 0 Sep 26 17:38 fic11
-r--r--r-- 1 michel michel 916 Sep 26 17:38 fic2
-rw-r--r-- 1 michel michel 0 Sep 26 17:38 titi
-rw-r--r-- 1 michel michel 106 Sep 26 17:38 toto
-r--r--r-- 1 michel michel 916 Sep 26 17:38 zorro
$ alias l='/usr/bin/ls -l'
$ alias l
l='/usr/bin/ls -l'
$ l
total 6
-rw-r--r-- 1 michel michel 0 Sep 26 17:38 fic1
-rw-r--r-- 1 michel michel 0 Sep 26 17:38 fic11
-r--r--r-- 1 michel michel 916 Sep 26 17:38 fic2
-rw-r--r-- 1 michel michel 0 Sep 26 17:38 titi
-rw-r--r-- 1 michel michel 106 Sep 26 17:38 toto
-r--r--r-- 1 michel michel 916 Sep 26 17:38 zorro
$
Nous obtenons ici un abrégé l pour exécuter, en fait la commande ls -l. Le shell examine les définitions d’alias avant le parcours des répertoires du PATH.
La commande type permet de savoir si un nom de commande est un alias, une commande interne du shell ou bien une commande externe (fichier ordinaire exécutable sur disque).
$ type type
type is a shell builtin
$ type cd
cd is a shell builtin
$ type l
l is an alias for /usr/bin/ls -l
$ type cal
cal is /usr/bin/cal
$
Une commande interne est une commande dont le code est intégré au shell lui-même et qui, de ce fait, ne génère pas de processus fils (fork). Lors de la recherche de commande, le shell consulte en premier les alias, puis ensuite les commandes internes, puis enfin les répertoires de la variable PATH. Si l’utilisateur fournit un chemin complet de commande ou bien s’il utilise un nom qui commence par la notation ./, la commande externe correspondante sera immédiatement localisée.
La commande unalias permet la suppression d’un alias.
$ unalias l
$ l
ksh: l: not found
$
La surcharge...
Fichiers de connexion
Lors de la connexion, le Korn shell exécute les commandes mentionnées dans des fichiers de paramétrage destinés à initialiser des variables d’environnement et à activer diverses fonctionnalités.
Le Korn shell exécute, en premier lieu, un fichier /etc/profile, géré par l’administrateur et commun à tous les utilisateurs. Ce fichier permet, entre autres, l’affichage d’informations générales, la recherche de courrier, le positionnement de certaines variables d’environnement.
Dans un deuxième temps, le shell exécute le contenu d’un éventuel fichier personnel .profile, situé dans le répertoire de connexion.
Parmi les tâches usuelles effectuées dans ce fichier, nous pouvons citer :
-
le paramétrage du prompt (variables PS1 et PS2),
-
le positionnement de certaines variables d’environnement,
-
le positionnement de certaines options du shell,
-
un appel éventuel à la commande umask (choix des droits par défaut).
Historiquement, par rapport à un souhait de compatibilité ascendante avec le Bourne shell, il est recommandé de prévoir un deuxième fichier pour l’activation de certaines fonctionnalités propres au Korn shell (alias, éditeur intégré...). Le nom de ce second fichier (traditionnellement .kshrc) doit être indiqué dans une variable d’environnement ENV.
Ce deuxième fichier est exécuté après le fichier .profile lors de la connexion. Par contre, si le shell est démarré de façon interactive, le fichier .profile ne sera pas exécuté, au profit de ce seul deuxième fichier.
Il ne faut pas confondre la commande env avec la variable...
Quelques exercices
1) Afficher son nom de connexion suivi d’un tiret bas et d’un nombre aléatoire.
2) Mettre dans son prompt le nom réseau du système suivi d’un tiret bas et du nom du répertoire courant, le terminer par un $ et un espace.
3) Mettre dans une variable chemin le nom complet de la commande cal.
4) Afficher les noms de fichiers constitués de trois caractères exactement dans le répertoire /etc.
5) La commande sleep permet de se mettre en attente pendant un certain nombre de secondes donné en argument. Lancer en arrière-plan une attente de 5 minutes puis lancer en premier plan une attente de 2 minutes. Stopper le deuxième processus et le relancer en arrière-plan. Éliminer le premier processus.
Solutions
1) Afficher son nom de connexion suivi d’un tiret bas et d’un nombre aléatoire.
echo ${LOGNAME}_$RANDOM
2) Mettre dans son prompt le nom réseau du système suivi d’un tiret bas et du nom du répertoire courant, le terminer par un $ et un espace.
PS1="$(hostname)_\$PWD$ "
3) Mettre dans une variable chemin le nom complet de la commande cal.
chemin=`which cal` # ou chemin=$(which cal)
# ou avec whence mais uniquement en ksh
4) Afficher les noms de fichiers constitués de trois caractères exactement dans le répertoire...