sujet 08

Université de Nice-Sophia Antipolis
Licence Mathématiques - MASS
Semestre 1
Semaine du 13 novembre 2014
Systèmes Informatiques
Travaux Pratiques – Séance n◦ 8
Compte rendu de TP
Vous allez déposer un fichier, dans votre boite de dépôt sur j@lon, en fin de TP dans lequel
vous inscrirez les réponses aux questions posées. Par réponse, j’entends un copier-coller à partir
de votre xterm des commandes que vous produisez, avec le résultat obtenu, accompagné d’un
commentaire si besoin.
Les questions à rendre sont indiquées par un astérisque en début de question.
Généralités (retour sur le cours)
L’interface de connexion textuelle d’U NIX se fait par l’intermédiaire d’un interprète de commandes, appelé shell. Le shell définit un langage de programmation incluant, entre autres, la notion de variables et de structures de commandes conditionnelles et itératives. Le mode d’utilisation courant du shell est le mode interactif. Mais les commandes du shell peuvent être également
placées dans un fichier, qu’on appelle alors script, et qui peut être exécuté comme une commande
ordinaire.
Le shell que vous utilisez se nomme zsh, mais il faut savoir qu’il en existe d’autres (sh, csh,
ksh, bash). Zsh utilise des fichiers de configuration qui se trouvent dans votre répertoire principal.
.zlogin : les commandes de ce fichier sont exécutées lorsque vous vous connectez.
.zlogout : les commandes de ce fichier sont exécutées lorsque vous vous déconnectez.
.zshrc : on y place les initialisations des sessions interactives (rattachées à un terminal).
.zshenv : on y définit des variables d’environnement.
Ces fichiers sont lus et interprétés par le shell lorsqu’ils sont présents dans votre répertoire
personnel. Cela signifie que vous pouvez en changer le contenu afin de personnaliser votre environnement de travail. Mais, en l’absence de ces fichiers, votre environnement de travail est tout
de même configuré à l’aide de valeurs définies par défaut.
Aspects de zsh liés à une utilisation interactive
L’utilisation habituelle d’un shell est interactive : l’utilisateur écrit des commandes dans un
terminal (par exemple une fenêtre xterm). Ces commandes sont interprétées ligne par ligne par le
shell. Comme vous l’avez déjà constaté, la saisie de lignes de commandes est souvent laborieuse
et pénible, mais elle peut être facilitée par plusieurs mécanismes proposés par zsh :
— l’achèvement automatique (en anglais completion) ;
— l’historique de commandes ;
— les alias.
Différents réglages sont offerts par le biais des options de zsh. Chaque option peut être activée
ou désactivée indépendamment pour chaque shell en cours d’exécution : si vous avez plusieurs
fenêtres xterm ouvertes, les options que vous changerez dans l’une n’affecteront pas l’autre.
2
La commande setopt suivie du nom de l’option permet d’activer une option, et la commande
unsetopt produit l’effet inverse 1 .
1) Dans une fenêtre xterm, affichez la liste des options activées par le shell courant et la liste
des options désactivées.
*2) Désactivez l’option correctall. Placez-vous dans votre répertoire /SI et tapez la commande ls TP9. Que constatez-vous ? Réactivez l’option et recommencez, expliquez.
Expansion des noms de fichiers
*3) Créez les trois fichiers de noms a15g, a9f et a8gf. Observez ensuite le résultat de chacune
des commandes suivantes :
— ls -d *<-15>*
— ls -d *<-10>?
— ls -d *<-10>[f]
— ls -d *<-10>f
Comme vous n’obtenez aucun fichier avec cette dernière commande, mettez en fonction l’option extendedglob puis recommencez. Expliquez les différents résultats obtenus pour les trois
premières commandes. Expliquez le cas de la dernière commande :ls -d *<-10>f avec et sans
extendedglob.
4) Testez et expliquez les commandes suivantes dans votre répertoire personnel :
ls -d *
setopt globdots
ls -d *
unsetopt globdots
L’achèvement automatique
Dans un souci de rapidité de saisie des lignes de commandes, il est possible d’utiliser le mécanisme d’achèvement automatique pour taper des noms de commandes et leurs paramètres, grâce
à la touche de tabulation Tab.
5) Déplacez-vous en une seule commande dans le répertoire /u/profs/carine. Mais, pour
éviter d’écrire tout le chemin, servez-vous autant que possible de la touche Tab. Constatez qu’en
cas d’ambiguïté, zsh propose une liste de toutes les possibilités et taper sur Tab permet de parcourir cette liste circulairement. Par exemple, une fois que vous avez saisi /u/profs/, au lieu de
taper carine en entier, ne tapez que les deux premières lettres, puis demandez l’achèvement :
/u/profs/ca+Tab : on vous propose le choix entre carine, caromel, ... Appuyez successivement plusieurs fois sur Tab pour bien comprendre ce qui se passe.
*6) Déplacez-vous maintenant dans /u/profs/grin, puis exécutez la commande ls. Pourquoi
n’en avez-vous pas l’autorisation, alors que vous êtes tout de même parvenu dans ce répertoire ?
L’historique des lignes de commandes
Zsh conserve dans un fichier, /.sh_history ou /.history, les n dernières lignes de commandes soumises. La valeur de n est paramétrable. On peut alors ré-utiliser les commandes anciennes par une série de commandes similaires à celles d’E MACS :
C-p ou ↑ pour accéder à la commande précédente ;
C-n ou ↓ pour accéder à la commande suivante ;
C-r pour chercher en arrière dans l’historique de façon incrémentale ;
Esc-p pour chercher en arrière dans l’historique une ligne commençant par le mot courant ;
Esc-n pour chercher en avant dans l’historique une ligne commençant par le mot courant.
1. Une autre façon pour désactiver une option consiste à activer son option opposée. L’option opposée d’une option
de nom XXXX s’obtient en insérant le préfixe NO devant son nom : NOXXXX. Par exemple, on peut activer l’option BEEP par
l’une des deux commandes suivantes : setopt BEEP ou unsetopt NOBEEP ; ou la désactiver par l’une des deux suivantes :
setopt NOBEEP ou unsetopt BEEP.
3
Le nombre maximum de lignes à conserver est indiqué par la valeur de la variable HISTSIZE.
Cette variable est déclarée et initialisée par défaut par zsh à 30.
7) Recherchez la première ligne de votre historique en utilisant ↑. Sans l’exécuter revenez à la
ligne la plus récente par ↓.
On peut modifier la ligne après avoir déplacé le curseur avec les flèches → ou ←, par C-b ou
C-f, par M-b ou M-f (un peu plus rapide), ou par C-a, C-e (beaucoup plus rapide !). Et lorsque
vous êtes à l’endroit de la modification, vous avez encore le choix entre C-d (supprime le caractère
suivant), M-d (supprime le mot suivant entier) ou C-k (supprime toute la fin de la ligne).
8) Exécutez la ligne de commande suivante echo tata titi toto tutu. Puis, pour chacune
des questions qui suivent, recherchez cette première commande dans l’historique, et modifiez-la
de la façon demandée avant de l’exécuter en vous efforçant d’utiliser les raccourcis les plus expéditifs :
— Remplacer toto par toti (possible par exemple en 3 raccourcis + la saisie du caractère i)
— Remplacer echo par ls en début de ligne (possible en seulement deux raccourcis + la saisie
de ls)
— Supprimer tata (possible en seulement 3 raccourcis)
— Remplacer toto par oto (3 raccourcis)
9) On peut retrouver directement une ligne de l’historique en recherchant une séquence de
caractères dont on sait qu’elle apparaît forcément dans la ligne recherchée. Pour commencer la
recherche, il faut utiliser C-r puis entrer un à un les caractères de la séquence recherchée :
— Recherchez la commande contenant toti. Remarquez qu’à chaque nouveau caractère saisi,
la recherche s’affine. . .
— Recherchez la dernière commande contenant ls (la deuxième de l’exercice précédent).
Remarquez qu’en faisant à nouveau C-r sans entrer de caractère supplémentaire, vous
obtenez l’avant-dernière commande contenant ls.
— Recherchez successivement dans l’historique toutes les commandes contenant ls. . .
10) Les différents répertoires dans lesquels vous vous déplacez par la commande cd sont
aussi mémorisés à la manière d’un historique. Déplacez-vous dans un de vos sous-répertoires,
puis dans le répertoire racine de toute l’arborescence. Tapez cd -. Où êtes-vous ? Où serez-vous
si vous retapez cette commande ?
Les alias
Rappel : l’intérêt d’un alias est de définir un nom abrégé, à utiliser à la place d’un nom de
commande long suivi d’options. La liste des alias définis dans le shell en cours est à consulter
avec la commande alias.
11) Affichez la liste des alias et regardez particulièrement les définitions de rm, cp et mv. En cas
d’égalité de noms d’un alias et d’une commande, c’est l’alias qui est utilisé en priorité. Ceci explique que lorsque vous utilisez rm, l’option -i (-i signifiant « interactif ») est systématiquement
utilisée.
12) Créez avec la commande touch un fichier vide essai. Tapez ls -l pour observer les
permissions de essai. Modifier les permission pour que vous seul ayez le droit d’exécution sur
ce fichier.
*13) Définissez un alias nommé exe de la sorte : alias exe='chmod ug+x'. À présent, utilisez
l’alias exe de la façon suivante : exe essai. Observez les nouvelles permissions de essai.
*14) Lancez un nouveau shell. Tapez exe essai. Est-ce que l’alias exe est connu dans ce nouveau shell ?
Les scripts (suite)
Une utilisation très importante du shell se fait par l’intermédiaire de scripts, qui sont tout
simplement des fichiers de commandes pour le shell. Les commandes contenues dans un script
peuvent être exécutées en transmettant le fichier en paramètre à un shell : zsh script.zsh
Le fichier script.zsh contient une suite de commandes reconnues par le shell zsh.
4
Une autre façon de procéder est de rendre le script exécutable en donnant la permission x.
Ainsi le script peut être exécuté comme n’importe quelle autre commande. . . ou presque.
La variable PATH
La plupart du temps, les commandes que vous exécutez sont externes au shell et font appel à
des programmes placés dans des fichiers de l’arborescence. Comment le shell, c’est-à-dire l’interprète de commandes, trouve-t-il ces fichiers ? Réponse : il consulte la variable d’environnement
PATH, dont la valeur est une liste de répertoires séparés par le symbole « : ».
Quand vous demandez l’exécution d’une commande, le shell commence par effectuer une
recherche dans chacun des répertoires spécifiés dans la variable PATH. S’il la trouve, il l’exécute,
sinon il renvoie le message « Command not found ».
15) Affichez et consultez la valeur de la variable PATH.
Pour des raisons de sécurité, il n’est pas bon que la variable PATH contienne le répertoire
courant (c-à-d .), ou alors seulement en dernière position. S’il en est absent, pour exécuter un
programme situé dans le répertoire courant, vous devrez taper : ./nom_du_programme.
Lorsque la commande est un script, le shell courant appelle un nouveau shell pour interpréter
les commandes du fichier. Par défaut, le shell qui est choisi est sh, mais on peut modifier ce comportement en plaçant une ligne initiale dans le fichier qui indique le shell que l’on désire. Cette
ligne commence par les caractères #!, suivis du nom absolu du shell à utiliser. Si le script précédent désire faire exécuter les commandes qu’il contient par zsh qui se trouve dans le répertoire
/bin/, sa première ligne sera : #!/bin/zsh.
Variables prédéfinies (rappel)
Le shell offre des variables prédéfinies qui facilitent sa programmation :
# : le nombre de paramètres ;
* : la liste des paramètres ;
$ : le pid du shell ;
0 : le nom du script courant ;
1 : le premier paramètre ;
2 : le deuxième paramètre ;
3 : le troisième paramètre ;
. . . et pour plus de détails : man zshparam.
16) Créez un script /bin/cmd.sh dont la seconde ligne (après #!/bin/zsh) est : ps -$1.
17) Exécutez ce script avec un paramètre. Constatez que ce dernier doit être une option
valide de la commande ps. Exécutez le script avec deux paramètres et remarquez que le second
paramètre n’est tout simplement pas utilisé dans le script.
18) Faites précéder l’appel de la commande ps de la ligne :
echo "Les paramètres d'appel du script $0 sont $*".
Exécutez alors votre script avec plusieurs paramètres.
19) Ajoutez dans cmd.sh l’appel à une commande permettant d’afficher le nombre de paramètres
passés au lancement du script.
*20) Créez un script show.sh qui accepte comme premier paramètre un fichier et comme second un nombre n, permettant d’afficher la nième ligne du fichier.
Il peut être utile dans un script de récupérer le résultat de l’exécution d’une commande (ou
d’un autre script !). Pour cela, il suffit d’entourer l’appel de cette commande par $(...). Par
exemple, ajoutez à cmd.sh :
echo "Voici la date et l'heure courantes : $(date)"
*21) Essayez l’option -F de la commande ls. À partir de $(ls), d’une boucle for do done et
de if then else fi emboîtés, écrire un script qui réalise la même chose, à la différence près que
5
les fichiers qui sont des exécutables doivent être indiqués par la lettre X, les fichiers qui sont des
répertoires par la lettre D, et les fichiers réguliers, par la lettre F.
*22) Ecrivez un script hasard.sh qui affiche 10 nombres au hasard entre 0 et 100.
Indication : pensez à une variable prédéfinie et à l’opérateur modulo.
Exemple de lancement du script et de son résultat :
$./hasard.sh
Dix nombres au hasard entre O et 100 :
59 50 39 29 14 24 41 96 5 7
*23) Ecrivez un script devine.sh qui correspond au jeu suivant :
L’utilisateur doit deviner un nombre entre 1 et 1000, il a 10 essais pour réussir.
Indication : pensez à utiliser la commande read.
Exemples :
~>devine.sh
Devinez un nombre entre 0 et 1000, vous avez 10 tentatives pour trouver :
1000
plus petit
500
plus petit
250
plus grand
370
plus petit
300
plus grand
350
plus grand
360
plus grand
365
Trouvé !
~>devine.sh
Devinez un nombre entre 0 et 1000, vous avez 10 tentatives pour trouver :
1
plus grand
2
plus grand
3
plus grand
4
plus grand
5
plus grand
6
plus grand
7
plus grand
8
plus grand
9
plus grand
10
plus grand
Vous avez atteint les 10 essais ! Le nombre à trouver était 120
6
Mécanismes d’évaluation
Les caractères ' et " permettent de délimiter une chaîne de caractères. Les apostrophes empêchent l’interprétation de tous les caractères spéciaux contenus dans la chaîne, contrairement
aux guillemets qui conservent notamment l’interprétation du $.
24) Pour les expressions suivantes, indiquez l’évaluation du shell et le résultat de l’exécution.
Exemple : x=p ; "$x"wd
Évaluation : affectation de la valeur p à la variable x ; substitution de la valeur x et concaténation avec la chaine ’wd’ −→ résultat : la chaine ’pwd’
Résultat final : le shell lance l’exécution de la commande pwd
x=p ; y=$xwd ; $y
x=p ; ${x}'wd'
x=p ; "${x}'wd'"
x=p ; y=${x}wd ; $y
x=p ; y='${x}"wd"'
x=p ; "${x}wd"