VIII. Le Shell d'Unix

Par Hugo ETIEVANT


  1. Les commandes
    1. Internes
    2. Externes
    3. Complexes
    4. Scripts
  2. Flux de données
    1. Entrée standard
    2. Sortie standard
    3. Sortie d'erreur standard
    4. Redirections
  3. Caractères spéciaux
  4. Les variables du Shell
    1. Variables d'environnement
    2. Autres variables
    3. Déclaration
    4. Manipulation
  5. Fichiers de commandes
    1. Exécution
    2. Paramètres
  6. Structures
    1. if then else
    2. case
    3. for
    4. while
    5. until
  7. Tests
    1. Chaînes de caractères
    2. Chaînes numériques
    3. Fichiers
    4. Autres opérateurs

Les commandes

Le Shell est un programme qui permet l'exécution de commandes qui affichent en générale un résultat à l'écran.

Le Shell est homologue à l'invite MS-DOS puisqu'il permet d'exécuter :

  • des commandes internes,
  • des commandes externes,
  • des commandes complexes,
  • des fichiers de commandes.

Tout programme en cours d'exécution est appelé processus. Le Shell en est un.

Commandes internes

Les commandes internes au Shell font partie intégrante du Shell et leur exécution n'implique pas la création d'un nouveau processus.

Exemples : pwd, cd.

Commandes externes

Ce sont des programmes binaires généralement situés dans le répertoire /bin que le Shell va exécuter sous la forme d'un nouveau processus.

Exemples : ls, gzip.

Commandes complexes

Les commandes complexes résultent de la combinaison de plusieurs commandes par l'intermédiaires de tubes.

Exemple :

$ ls -a1 | head -n5 | nl
1 .bashrc
2 .XAutority
3 bin
4 lettre.txt 
5 tp6.c

Fichiers de commandes

Appelés aussi scripts Shell, ces fichiers textes regroupent une succession ordonnée de commandes et de structures de contrôles. Ecrire un script revient à faire de la programmation.

Exemple :

if [ $# -eq  1 ]
then if [ -f "/bin/$1" ]
     then echo "Commande externe."
     fi
else echo "Syntaxe: $0 commande"
fi

Les flux de données

Les flux de données du Shell sont transportés par trois voies différentes :

  • l'entrée standard
  • la sortie standard
  • la sortie d'erreur standard

Entrée standard

L'entrée standard est le canal d'entrée des données qui est utilisé par le système. Par défaut c'est le clavier.

Ainsi, les commandes du Shell prennent leur paramètres sur l'entrée standard.

Sortie standard

La sortie standard est le canal de sorties des données. C'est par ce canal que transitent les données résultant de l'exécution d'une commande. C'est en général un terminal, c'est-à-dire l'écran.

Ainsi, les commandes du Shell écrivent très souvent des résultats sur la sortie standard.

Sortie d'erreur standard

La sortie d'erreur standard est le canal par lequel les messages d'erreurs transitent, c'est en général l'écran. Il arrive quelque fois qu'une fenêtre soit spécialement dédiée à ce canal.

Dès qu'un code d'erreur est généré par une commande, il est envoyé un message sur ce canal.

Redirections

Il est possible de changer temporairement les entrées et sorties standard lors de l'exécution d'une commande.

Par exemple on souhaite écrire dans un fichier la liste des fichiers d'un répertoire. La commande ls permet de lister les fichiers d'un répertoire. Cette commande envoie le résultat de sa recherche sur la sortie standard (écran).

Exemple :

$ ls
amoi.c           montage.jpg     tp3.c
lettre.doc       tp1.c           zizitop.mp3
monprog.c        tp2.c           

Pour rediriger la sortie standard sur un fichier, on utilise le caractère spécial >.

Exemple :

$ ls > liste.txt

Si on affiche à l'écran le contenu du fichier, on vera qu'il contient ce que la commande aurait du afficher à l'écran.

Exemple :

$ cat liste.txt
amoi.c           montage.jpg     tp3.c
lettre.doc       tp1.c           zizitop.mp3
monprog.c        tp2.c           

Le caractère > permet de créer le fichier si celui-ci n'existe pas lors de l'exécution de la commande. Si le fichier existe déjà, sont contenu est écrasé.

Pour conserver le contenu du fichier intact et écrire à sa suite, on utilise le caractère spécial >>.

Exemple :

echo "Liste de mon répertoire" >> liste.txt

La commande echo permet d'afficher du texte sur la sortie standard qui est ici redirigée vers le fichier liste.txt à la suite duquel on écrit la chaîne de caractères passée en argument.

Exemple :

$ cat liste.txt
amoi.c           montage.jpg     tp3.c
lettre.doc       tp1.c           zizitop.mp3
monprog.c        tp2.c           
Liste de mon répertoire

On voit que le contenu du fichier n'a pas été écrasé et qu'il contient une phrase en plus.

Le tableau suivant récapitule les caractères spéciaux de redirection.

CaractèreDescription
>Redirige la sortie standard.
>>Redirige la sortie standard sans écrasement.
<Redirige l'entrée standard.
2>Redirige la sortie d'erreur standard.
2>>Redirige la sortie d'erreur standard sans écrasement.


Caractères spéciaux

En plus des caractères de redirection des flux standards de données, le Shell possèdent des caractères dont la signification est très... spéciale, les voici regroupés dans le tableau suivant.

CaractèreDescription
*Métacaractère qui remplace n'importe quelle chaîne de caractères (même vide).
Exemple : cp * DATA copie tous les fichiers dans le répertoire DATA.
?Métacaractère qui remplace un caractère quelconque.
;Permet de séparer plusieurs commandes écrites sur une même ligne.
Exemple :
cp *.c DATA; tar cvf data.tar DATA copie tous les fichiers d'extention .c
dans le répertoire DATA et les archive dans le fichier data.tar.
( )Regroupe des commandes.
Exemple :
(echo "Liste :"; ls ) > liste.txt
écrit la chaîne Liste : et la liste des fichiers du répertoire courant dans le fichier liste.txt.
&Permet le lancement d'un processus en arrière plan. Cela permet d'exécuter d'autres commandes pendant qu'un processus est en marche.
Exemple : netscape&.
|Permet la communication par tube entre deux commandes.
Exemple : ls -1 | file la commande de listage des fichiers du répertoire (ls) envoie chacun d'eux à la commande qui permet de connaître le type d'un fichier (file).
#Introduit un commentaire. Donc tout ce qui suit ce caractère dans une ligne est ignoré par le Shell.
Exemple : # ceci est un commentaire.
\Déspécialise le caractère qui suit. C'est-à-dire que si le caractère qui suit celui là est un caractère spécial alors le Shell l'ignorera.
Exemple : echo Bon\*jour affiche bon*jour à l'écran.
'...'Défini une chaîne de caractères qui ne sera pas évaluée par le Shell.
Exemple : echo '*?&' affiche sur la sortie standard les caractères spéciaux *?& sans les interpréter.
"..."Défini une chaîne de caractères dont les variables seront évaluées par le Shell.
Exemple : echo "Vous êtes $USER." affiche Vous êtes + la valeur de la variable $USER.
`...`Défini une chaîne de caractères qui sera interprétée comme une commande et remplacée par la chaîne qui serait renvoyée sur la sortie standard à l'exécution de la dite commande.
Exemple : echo `pwd` >> liste.txt écrit à la fin du fichier le chemin et le nom du répertoire courant. Le caractère spécial utilisé s'obtient par la combinaison de touche : AltGr + 7 (c'est l'accent grave).


Les variables du Shell

Les variables d'environnement

Le Shell possède comme MS-DOS des variables d'environnement qui permettent de garder en mémoire des informations importantes telles que le login de l'utilisateur (stocké dans la variable $USER) ainsi que son répertoire de connexion ($HOME), la liste des répertoires dans lequels aller chercher les exécutables des commandes externes ($PATH), et bien d'autres encore...

La commande env affiche la liste de toutes les variables d'environnement du Shell avec leurs valeurs.

Le tableau suivant résume quelques variables affichée par env.

Variable=ValeurDescription
PWD=/home/hugoStocke le chemin et le nom du répertoire courant.
HOSTNAME=
localhost.localdomain
Nom du serveur.
HISTSIZE=1000Taille de l'historique. L'historique garde en mémoire les dernières commandes passées au Shell. Ces dernières sont accessibles successivement par la touche fléchée vers le haut.
LANGUAGE=frSuffixe de la langue du système.
PS1=[\u@\h \W]\$Chaîne apparaissant à l'invite du Shell.
USER=hugoNom de l'utilisateur.
DISPLAY=unix:0.0Adresse du terminal d'affichage.
SHELL=/bin/bashChemin et nom du programme Shell (il en existe plusieurs différents).
HOME=/home/hugoChemin du répertoire de connexion.
PATH=:/usr/local/bin:
/bin:/usr/bin:
/usr/X11R6/bin
Liste des répertoires où chercher les exécutables des commandes externes.

Autres variables

VariableDescription
$$PID du processus Shell en cours.
$!PID du dernier processu lancé en background.
$?Code erreur de retour de la dernière commande (0:vrai; sinon faux).

Déclaration

L'utilisateur peut déclarer facilement de nouvelles variables par l'affectation directe d'une valeur.

Syntaxe : nom=valeur

La valeur de la variable peut être numérique ou être une chaîne de caractère, sont format n'a pas d'importance.

Exemple : EMAIL=cyberzoide@multimania.com Manipulation

Une variable peut être utilisée dans n'importe quelle circonstance du moment que c'est dans le Shell. Son nom doit être précédé du signe dollard ($) et être entre accolades ({}) si un autre mot lui est contigu.

Exemples :

$ echo $EMAIL
cyberzoide@multimania.com

$ echo "Mon mail : $EMAIL"
Mon mail : cyberzoide@multimania.com

$ echo 'Mon mail : $EMAIL'
Mon mail : $EMAIL

Dans le premier exemple, la variable EMAIL est passé directement en paramètre à la commande echo qui l'affiche après que le Shell en ait évalué la valeur.

Dans le second exemple, une chaîne contenant la même variable est passée en paramètre à echo. Les doubles quotes sont des caractères spéciaux ("...")qui obligent le Shell a évaluer la valeur des variables que contient la chaîne entre double quote. La commande echo affiche donc la chaîne à l'écran.

Et enfin, cette fois les simples quotes interdisent au Shell d'évaluer la valeur de la variable. Donc echo affiche la chaîne brute.

Autres exemples :

$ moi=CyberZoïde; echo $moi
CyberZoïde

$ phrase="Bonjour $moi"; echo $phrase
Bonjour CyberZoïde

$ rep=`pwd`; echo $rep
/home/hugo/data

Dans le second exemple, la variable est entre accolades afin que le Shell la distingue des caractères qui suivent.

Dans le dernier exemple, la variable rep contient une chaîne entre accents graves, ce qui oblige le Shell à l'interpréter comme une commande et à la remplacer par la chaîne qui serait renvoyée sur la sortie standard à l'exécution de la dite commande.


Fichiers de commandes

Les fichiers de commandes (scripts) sont des fichiers textes qui contiennent des commandes du Shell ordonnées par des structures de contrôle.

Exécution

Pour exécuter un script, plusieurs solutions :

  • Syntaxe : sh script
    Cette syntaxe lance un nouveau processus Shell qui lit ses commandes dans le fichier script. Ce fichier doit être accessible en lecture.

  • Syntaxe : . script
    Le terminal est momentanément remplacé par le fichier script accessible en lecture (pas de nouveau processus créé).

  • Syntaxe : script
    Lance un nouveau processus Shell qui lit ses commandes dans le fichier qui doit être accessible en lecture et en exécution.

  • Syntaxe : exec script
    Le Shell courant est remplacé par un processus Shell qui lit ses commandes dans le fichier qui doit être accessible en lecture et en exécution.

Paramètres

Il est possible d'exécuter un script en lui passant des arguments comme pour n'importe quelle autre commande.

Le tableau suivant résume les variables accessibles à un script :

VariableDescription
$#Nombre d'arguments.
$*Liste des arguments.
$0Nom de la commande.
$1Valeur du premier paramètre.
$iValeur du ième paramètre si i compris entre 1 et 9.
$9Valeur du neuvième paramètre.


Structures

if then else

Structure conditionnelle binaire : suivant qu'une condition est vrai ou fausse on exécute un bloc ou on ne l'exécute pas.

if condition
then instruction
fi

Si la condition est vraie, alors instruction (qui peut être un bloc d'instruction) est exécutée.

if condition
then instruction1
else instruction2
fi

Si la condition est vraie, alors instruction1 est exécutée et la seconde est ignorée, sinon c'est instruction2 qui est exécutée et la permière est ignorée.

if condition1
then instruction1
elif condition2
then instruction2
fi

elif est équivalent à else if. Ainsi l'instruction2 n'est exécutée que si condition1 est fausse et que condition2 est vraie.

case

Structure conditionnelle à choix multiples : suivant la valeur de l'expression chaine, on peut faire exécuter un large panel d'instructions.

case chaine in
motif_1) instruction1;;
motif_2) instruction2;;
...
motif_k) instructionk;;
esac

Si la chaine de caractères est semblable au motif_1 (qui est une chaîne d'expansion de chemin, accepte les méta caractères * ?, [], {} et ~) alors l'instruction1 est exécutée.

La chaine peut tout à fait vérifier simultanément plusieurs motifs différents, dans ce cas de figure les instructions (ou blocs d'instructions) correspondantes seront tous exécutés.

for

Structure répétitive bornée : boucle dont on connait avant le premier passage le nombre total d'itérations.

for variable in ensemble
do
instructions
done

On fait donc varier la variable en lui faisant prendre successivement toutes les valeurs de l'ensemble.

while

Structure répétitive tant que la condition est vraie.

while condition
do
instructions
done

Boucle dont les instructions sont exécutées tant que l'expression condition est vrai.

until

Structure répétitive jursqu'à ce que la condition soit vraie (i.e. tant qu'elle est fausse).

until condition
do
instructions
done

Boucle dont les instructions sont exécutées tant que l'expression condition est fausse.


Tests

Les conditions des structures peuvent être évaluées grace à la commande test.

Chaînes de caractères

test -z chaine
Renvoie vrai si chaine est vide.

test -n chaine
Renvoie vrai si chaine n'est pas vide.

test chaine_1 = chaine_2
Renvoie vrai si les deux chaînes sont égales.

test chaine_1 != chaine_2
Renvoie vrai si les deux chaînes ne sont pas égales.

Chaînes numériques

test chaine_1 opérateur chaine_2
Renvoie vrai si les chaînes chaine_1 et chaine_2 sont dans l'ordre relationnel défini par l'opérateur qui peut être l'un parmi ceux du tableau ci-après.

OpérateurSignification
-eq=
-ne<>
-lt<
-le<=
-gt>
-ge>=

Fichiers

test condition fichier
Renvoie vrai si le fichier vérifie la condition qui peut être l'une parmi celles décrites dans le tableau ci-après.

OpérateurRenvoie vrai si
-pc'est un tube nommé
-ffichier ordinaire
-drépertoire
-cfichier spécial en mode caractère
-bfichier spécial en mode bloc
-raccès en lecture
-waccès en écriture
-xaccès en exécution
-sfichier non vide

Autres opérateurs

Il est possible de combiner des tests grâce au parenthésage et à l'utilisation des opérateurs booléens du tableau suivant :

OpérateurSignification
!négation
-aconjonction (et)
-odisjonction (ou)