Le Korn shell, un environnement normalisé multiplate-forme

par Jean-Michel Chenais, SIC-Exploitation
Comme annoncé dans le dernier numéro du FI au sujet de la mise en place d'Unicos 8.0 sur le serveur Pascal, de nombreuses nouveautés ont été introduites et sont désormais disponibles. Parmi celles-ci, une d'importance concerne la définition chez Cray du nouvel interpréteur de commandes dénommé Korn shell. Cet événement n'est pas sans signification: il consacre le principe de la disponibilité chez tous les constructeurs d'une interface Unix répondant à une norme, la référence IEEE Posix 1003.2 en l'occurrence. Et cela est valable depuis quelques temps déjà pour tous les systèmes faisant partie des lignes de produits supportés officiellement par l'EPFL. En d'autres termes, le Korn shell existe pour les systèmes Sun (Solaris), HP, SGI, DEC Alpha actuellement localisés à l'EPFL, du moins, dans leurs révisions les plus récentes. Et il en est de même chez Cray pour le système Unicos, en fait, déjà depuis la version précédente.

Il existe de nombreux autres langages interpréteurs, génériquement dénommés shells, généralement disponibles dans le domaine public, mais parmi ceux-ci aucun n'a fait l'objet d'une définition officielle. Le C shell en est certainement le plus connu, et malgré cela, il est encore largement utilisé. Mais, à en lire les informations contenues dans les News (groupe comp.unix.shell), il souffre de nombreuses inconsistances, agrémentées de bugs. Il ne serait plus ni développé ni même supporté par l'équipe de Berkeley. De nombreuses variantes récentes, issues d'une part du Bourne shell et d'autre part du C shell, ont vu le jour. Aucune de celles-ci n'est (encore) officiellement reconnue, même si elles sont de conception plus moderne et évoluée que le Korn shell qui date déjà de 88.

Cet article n'a d'autre but que de décrire dans ses grandes lignes les spécificités de ce nouveau shell Posix, donc du Korn shell. Les usagers seront ainsi informés et pourront en meilleure connaissance de cause se déterminer pour une interface et une méthode de travail indépendante du matériel utilisé (station de travail, serveurs centraux ou décentralisés).

Caractéristiques d'ensemble

Le Korn shell, comme son prédécesseur le Bourne shell, résulte des travaux de conception et de développement de personnes qui ont chacune transmis leur nom à leur oeuvre respective. Messieurs Steve Bourne et David Korn ont tous deux travaillé, (à des époques différentes) à la compagnie AT&T Bell Laboratories. Les deux langages ont de nombreux points communs, et le passage du plus ancien au plus récent, sur-ensemble du précédent, ne pose pas de problème particulier, car ils sont pratiquement compatibles. Donc pas de problème pour faire tourner d'anciens scripts dans le nouveau shell. Toutefois, afin de tirer le meilleur parti de son effort de programmation, il convient de suivre les quelques nouvelles règles syntaxiques du Korn shell. Les principales propriétés du nouveau shell sont les suivantes :
  1. rappel les commandes précédentes, avec possibilités d'édition, selon les modèles vi ou emacs;
  2. possibilités de complétion automatique des pathnames, donc plus précisément des noms d'objets (fichiers ou directoires)
  3. disponibilité d'un mécanisme d'history;
  4. possibilité de définir des alias et des functions;
  5. disponibilité d'une arithmétique entière de base quelconque entre 2 et 36, relativement facile à utiliser;
  6. opérateur de chaînes et de sous-chaînes de caractères;
  7. possibilité de définir des variables simples ou indicées
  8. disponibilité de toutes les structures conditionnelles et itératives traditionnelles (if, while, for, until, case)
  9. possibilité de créer des menus (select)
  10. introduction de co-process
  11. fichiers d'environnement .profile et $ENV
  12. et encore une multitudes de petites choses, comme l'interception des signaux d'erreurs (trap), les opérations d'ouverture/fermeture de fichiers, les nouvelles variables d'environnement, etc.

Rappel des commandes

Toutes les commandes s'empilent normalement dans un fichier d'history, à partir duquel les commandes peuvent être rappelées et éventuellement modifiées: très utile, plus agréable et efficace qu'un cut and paste fractionné effectué avec la souris. L'entrée dans le mode «rappel des commandes» est activé en pressant la touche ESC (escape). L'introduction subséquente (ici en mode vi) de commandes de rappel permet de rechercher une commande précédente selon divers critères. Tout se passe virtuellement comme si vous étiez dès cet instant dans une session d'édition, et en train d'effectuer une recherche de chaîne dans le fichier d'history, en utilisant la syntaxe de votre éditeur préféré (vi ou emacs). Une recherche ascendante de chaîne (touche N) ou descendante (touche n) peut être répétée, jusqu'à l'occurrence désirée, qui peut alors être éditée. De même, un simple rappel séquentiel des commandes précédentes peut être activé avec les touches - et + La touche return termine la session d'édition de la commande, qui est alors envoyée au système pour exécution.

Un nom de fichier peut être complété automatiquement (touche back-slash après ESC). En cas d'ambiguïté, la complétion automatique peut être lancée avec ou sans affichage des différents choix possibles (touche = après ESC).

Le choix de l'éditeur est déterminé par la valeur d'une variable d'environnement EDITOR (égale à /usr/bin/vi ou /usr/bin/emacs), ou d'un paramètre d'appel au Korn shell (set -o vi ou set -o emacs).

Alias et function

Les alias permettent de nommer une commande simple fréquemment utilisée sous une forme abrégée. Il existe plusieurs types d'alias, déterminés par différents attributs (-x pour exported, -t pour tracked).

Les functions ont pour rôle d'associer un nom à tout un ensemble de commandes correspondant à une tâche donnée. Les fonctions peuvent aussi être exported, comme pour les alias.

Les alias et les functions avec l'attribut exported sont utilisables (seulement) sans autre par tout script lancé dans le shell courant, mais ne faisant explicitement pas référence à une invocation séparée du Korn shell. Plus concrètement, le script ne doit pas disposer de la chaîne #!/bin/ksh dans sa première ligne. Pour avoir accès à ces alias et fonctions dans le cas d'une invocation séparée du shell, il faut réactualiser ces définitions. C'est la raison pour laquelle il est conseillé de placer les alias et les functions nécessaires dans un fichier d'environnement, pointé par la variable ENV, et qui est exécuté à chaque invocation séparée du shell (de façon similaire à l'appel au fichier .cshrc du C shell).

Arithmétique entière

Il n'est souvent pas aisé d'effectuer des calculs, mêmes simples, avec les shells en général (le comble pour un ordinateur). La commande let du Korn shell, (entre autres possibilités), offre une réponse relativement pratique à cette difficulté. Cette commande permet de considérer la variable à laquelle elle s'applique comme devant contenir une valeur numérique entière, et non une chaîne de caractères numériques. Il suffit de comparer les séquences suivantes:
     A=5 ; B=7 ; C=$A+$B     ; echo $C affiche : 5+7
A=5 ; B=7 ; let C=$A+$B ; echo $C affiche : 12

De même, l'emploi d'opérateurs s'appliquant à des nombres impliquent les transformations de représentations internes avant comparaison. Ainsi:
     A=002 ; let B=2 ; if [[ $A -eq $B ]] vérifie l'égalité

Les opérateurs <, >, = par contre agissent sur des chaîne de caractères:
	
     if [[ "$TERM" = "xterm" ]]

Dans cette syntaxe, le signe = est un opérateur d'égalité, mais pas d'affectation. Il doit être précédé et suivi d'au moins un caractère blanc.
Les expressions conditionnelles dans le Korn shell en sont parfois délicates à traiter correctement.

Variables simples et indicées

L'opération d'assignation s'effectue en utilisant le signe =. Aucun espace ne doit précéder ni suivre cet opérateur d'affectation.
     A=15 est correct, mais pas : A  =  15

L'assignation à une variable du résultat d'une commande s'effectue à l'aide de la syntaxe suivante $(expression). Dans le cas d'une variable vecteur, nous avons la syntaxe:
     set 	-A DATE=$( date )
echo ${DATE[*]}

affiche tous les éléments du vecteur, soit:
   Wed Mar 30 14:12:57   MET 1994

Chacun des éléments d'un vecteur de N éléments est accessible à l'aide d'un indice allant de 0 à N-1. Ainsi:
    echo ${DATE[3]}     donne 14:12:57

On peut obtenir le nombre d'éléments d'un vecteur:
    echo ${#DATE[*]}     donne 6	

Les fichiers d'environnement sur Pascal

Les fichiers d'environnements du Korn shell modifiables par l'usager sont localisés dans le «home directory» de chaque usager, et se nomment .profile et . envfile. Avec la mise en place d'Unicos 8 sur le serveur Pascal, ces fichiers ont été remis à jour, tout en préservant la version précédente. Suite à la disparition planifiée du Bourne shell, remplacé d'office dès maintenant par le Korn shell, ces fichiers ont dû subir quelques transformations. La variable d'environnement ENV est définie à .envfile, et ce fichier est censé contenir les alias et functions des usagers. Les environnements proposés, invoqués depuis ces fichiers, contiennent une synthèse des commandes les plus communément utilisées dans le monde Unix. De plus, des adjonctions spécifiques à X-Window sont invoquées automatiquement lorsque la variable TERM est définie comme xterm. Ainsi le prompt est reporté dans la barre de titre de chaque fenêtre, et représente le directoire courant. Lors de la toute première connexion à Pascal, tout nouvel usager se voit proposer les seuls deux shells officiellement à disposition (ksh et csh). Se reporter à l'information disponible sur Pascal par le système info. et consulter les items #6 et #7 pour plus détails. A noter que les shells issus du domaine public, et disponibles en tant que tels sur Pascal (comme tcsh), posent quelques problèmes. Il ne disposent pas des commandes build-in généralement disponibles sur le système Unicos, car ils n'incorporent pas les modifications que Cray a du entreprendre avec les seuls shells standards et supportés.

Bibliographie

Les ouvrages suivants sont proposés, pour une prise de connaissance plus complète du Korn shell, dont le présent article n'a fait que survoler quelques éléments essentiels. Cette liste n'est pas exhaustive. Les man pages constituent également un moyen de référence fort utile, bien que parfois difficile pour une approche initiale.

article paru dans le Flash informatique no 4 du 19 avril 1994