TP #2 : Premier script shell

Responsables : Jean-Patrick Gelas, Nicolas Louvet

Version : 0.1a (04/2021)


Prérequis : Pour faire ce TP il est préférable de maitriser les notions et commandes vu au cours du TP1.

Objectif : Valider les compétences vu dans le TP1 et découvrir de nouvelles commandes.

Premier script Shell

Dans le TP1 nous nous sommes contenté de saisir des instructions sur la ligne de commande. A présent nous allons automatiser la saisie de ces commandes en les notant dans un fichier. On appelera ce fichier un script shell.

La première ligne du fichier (ou script) est toujours la même. Elle indique au système quel interpréteur (ou quel logiciel) doit être utilisé pour éxécuter les instructions contenu dans ce script.

#!/bin/bash

Remarque : On appel cela le shebang.

Ouvrez votre éditeur de texte favori. Par exemple nano. Saisissez-y les lignes ci-dessous.

#!/bin/bash
echo "Hello world"
exit 0

Remarque : La dernière instruction (exit 0) n'est pas strictement nécessaire mais c'est une bonne habitude à prendre. Nous reviendront dessus plus tard.

Sauvegardez ces quelques lignes dans un fichier nommé hello.sh. Notez que l'extension .sh est une convention de nommage. Il permet de savoir que le fichier contient très probablement des commandes "compréhensible" par un interpréteur shell (ex: bash).

Sortez de l'éditeur. Un script shell ne nécessite pas d'être compilé (comme un programme en C par exemple), néanmoins pour nous simplifier la vie nous allons lui donner les droits d'exécution. Pour ce faire saisissez la commande suivante.

chmod u+x hello.sh

A présent vous pouvez l'exécutez en l'appelant par son nom préfixé de ./.

./hello.sh

Question 1 : Éditez le fichier hello.sh et ajoutez-y quelques instruction echo afin qu'il affiche à l'écran :

Hello world
Je suis vivant !!!
Au revoir

Remarque : Toutes les instructions qui seraient situées après la commande exit 0 ne seront pas exécutée.

Conseil : Vous pouvez dés à présent réaliser l'Activité 1 de ce sujet de TP.

Les variables ($)

En shell la notion de variable existe. Il en existe de nombreuses pré-définies. Mais vous pouvez également définir vos propres variables. Notez que toutes les variables commencent par le caractère dollar $.

Variables d'environnements

Voici quelques exemples des variables dites d'environnement. Celles-ci sont définit par le système.

echo $USER  # affiche le login de l'utilisateur courant
echo $SHELL # affiche l'interpréteur courant
echo $HOME  # affiche le répertoire de connexion
echo $HOSTNAME  # affiche le nom de la machine
...

Vous pouvez utiliser ces variables dans un script shell. Par exemple :

#!/bin/bash
echo "L'interpréteur utilisé est $SHELL"
exit 0

Question 2 : Rédiger un petit script qui affiche à l'écran la phrase suivante en remplacant ce qu'il y a entre parenthèse par le contenu des variables d'environnement adéquats.

Bonjour (login de l'utilisateur), je suis (nom de la machine) pour vous servir.




Variables personnelles

Vous pouvez également définir vos propres variables. Elles s'initialisent sans le caractère $ mais ensuite pour appeler leur contenu il faudra bien les préfixer avec un $. Voici un exemple.

#!/bin/bash
first_name="Harry"
last_name="Potter"
age=24

echo "Bonjour, je suis $first_name $last_name."
echo "J'ai $age ans"

exit 0

Important : Ne pas mettre d'espace avant et après le symbole d'affectation =.

Variables de paramètres positionnels

Comme pour n'importe quel autre langage de programmation il est possible de récupérer les paramètres passé à un script. Les paramètres sont accessibles via leur numéro de rang précédé d'un caractère $. Par exemple le premier paramètre est stocké dans la variable $1, le second dans $2, etc. Saisissez le script suivant que l'on nommera showparams.sh et faites des essais.

#!/bin/bash
echo "parametre 1: $1"
echo "parametre 2: $2"
echo "parametre 3: $3"
exit 0

Voici quelques exemples d'essai à faire

$ ./showparams.sh Kevin Bob Stuart  # trois parametres séparés par des espaces
$ ./showparams.sh "Anakin Skywalker" "Dark Vador" "Seigneur Sith" # des paramètres contenant des espaces
$ ./showparams.sh Leon      # un seul paramètre
$ ./showparams.sh Joe William Jack Averell  # plus de trois paramètres
$ ./showparams.sh       # pas de paramètres !!!

Question 3 : Modifier le script showparams.sh pour qu'il affiche aussi Averell !

Question 4 : Qu'est-ce que contient la variable positionnelle $0 ?


Stocker le résultat d'une commande

Une variable d'un script shell peut être utilisée pour stocker le résultat d'une commande. Ou plus exactement la sortie d'une commande (ce qui s'affiche à l'écran).

Soit la commande date. Essayez la dans votre terminal.

$ date
lun. 03 mai 2021 11:09:29 CEST

La commande date appelée sans paramètre affiche la date et l'heure courante. C'est une chaîne de caratères qui peut être stockée dans une variable. Pour ce faire nous vous invitons a utiliser la syntaxe suivante: $(commande). Voici un exemple.

$ la_date_et_heure_du_jour=$(date)
$ echo "Aujourd'hui nous sommes $la_date_et_heure_du_jour"
Aujourd'hui nous sommes lun. 03 mai 2021 11:09:29 CEST

Remarque : Vous trouverez dans certains script l'usage d'anti-quote (`commande`) en lieu et place de la notation $(commande).

Quelques commandes utiles

Dans cette section nous allons découvrir quelques commandes utiles qui viennent en complément du TP1

tar

La commande tar permet de créer une archive, c'est à dire un fichier pouvant contenir plusieurs fichiers ou même un sous arbre de votre système de fichiers (i.e. des dossiers et des fichiers).

Cette commande est très utile lorsque vous voulez envoyer plusieurs fichiers à un collègue puisque une fois l'archive construite vous n'aurez qu'un seul fichier a envoyer par email par exemple. Notez que l'archive peut aussi être compressée pour gagner de l'espace disque.

C'est partie ! Créez un dossier TP2 dans lequel vous créerez deux sous-dossiers Python et Java. Dans chacun de ces sous-dossiers créez respectivement un fichier projet.py et projet.java.

Représentez par un schéma l'arborescence que vous venez de créer.




Remarque : Dans le cadre de cet exercice peu importe que les fichiers projet.[py|java] soient vide.

Positionnez vous au dessus du répertoire TP2 (quand vous faite un ls vous devez le voir dans la liste). La commande suivante va vous permettre de créer une archive du répertoire TP2 et de son contenu.

$ tar cvf archive-TP2.tar TP2

Question 5 : Relevez la taille du fichier archive-TP2.tar en octets.


Visualisez le contenu du fichier archive-TP2.tar avec la commande cat. Comme vous pourrez le constater ce n'est pas très clair. Pour visualiser le contenu d'une archive utilisez l'option t de la commande tar.

$ tar tf archive-TP2.tar

A présent supposons que vous venez de recevoir cette archive par email. Copiez la dans le répertoire /tmp de votre poste (ce répertoire existe déjà et est bien adapté pour faire des tests).

Positionnez vous dans /tmp et ouvrez l'archive.

$ cd /tmp
$ tar xvf archive-TP2.tar
$ ls -l

Un répertoire TP2 a du apparaitre dans /tmp. Bravo !

Question 6 : Il existe une option z qui permet en plus de compresser l'archive lors de sa création. Refaite l'exercice précédent en utilisant cette option de compression et comparé la taille (en octet) de l'archive obtenue.

$ tar cvzf archive-TP2.tgz TP2
$ tar tzf archive-TP2.tgz
  ...
$ tar xvzf archive-TP2.tgz

Remarque : La convention veut que nous utilisions l'extension .tgz lorsque l'archive est compressée.

Question 7 : A quoi servent les option c,x,v,z,f,t ?

c :
x :
v :
z :
f :
t :

gzip

Les commandes gzip et gunzip permettent respectivement de compresser et décompresser un unique fichier.

$ ls -l MonGrosFichier.txt
-rw-r--r-- 1 jp wireshark 100kB avril 30 09:38 MonGrosFichier.txt
$ gzip MonGrosFichier.txt
$ ls -l MonGrosFichier.txt.gz
-rw-r--r-- 1 jp wireshark 20kB avril 30 09:39 MonGrosFichier.gz
$ gunzip MonGrosFichier.txt.gz
$ ls -l MonGrosFichier.txt
-rw-r--r-- 1 jp wireshark 100kB avril 30 09:40 MonGrosFichier.txt

Question 8: Prenez le temps d'essayer sur un de vos fichier texte et expérimentez avec les options -9 et -1.

Remarque : La compression d'un fichier déjà compressé ne fonctionne pas bien. Bref, inutile de compresser un fichier mp3, une photo jpeg, ou une vidéo.

diff

La commande diff permet de comparer deux fichiers. Il suffit de lui passer en paramètre deux fichiers.

$ diff fichier1.txt fichier2.txt

Si les deux fichier sont identiques, rien ne s'affiche à l'écran. Si les fichier diffères alors une description précise des différences apparaitra à l'écran.

Question 9: Créez un fichier, nommé original.txt dans lequel vous saisirez quelques lignes de texte. Dupliquez ensuite ce fichier avec la commande cp original.txt clone.txt. Appliquez la commande diff original.txt clone.txt. Qu'est ce qui apparait à l'écran ? (Rien !). Modifiez un unique caractére dans le fichier original.txt. Appliquez à nouveau la commande diff.

Remarque : Retenez que si la commande diff n'affiche rien c'est que les deux fichiers sont identique.

Activités

Activité 1

Reprenez l'Activité 1 du TP1. Notez cette fois-ci toutes les commandes saisie pour créer l'arborescence dans un script shell que vous nommerez buildTree.sh. Rendez ce script exécutable et testez le dans le répertoire /tmp.

Activité 2

Soit le script suivant, nommé starkindustries.sh exécuté par l'utilisateur tony sur une machine nommée jarvis. Le script est lancé avec pour paramètre start et mk42.

$ ./starkindustries.sh start mk42

Après avoir lu le script ci-dessous, notez sur une feuille ce qu'il devrait afficher à l'écran.

#!/bin/bash

version="1.0"
delay=5
french_text="Aujourd'hui nous sommes le"

echo "Bonjour $USER. Je suis $HOSTNAME. A votre service."
echo "version $version ($0)"

echo "Commande : $1"
echo "Armure \"$2\" en cours d'initialisaton..."
echo "Temps d'attente estimé : $delay secondes."

sleep $delay

echo $3
date_du_jour=$(date)
echo $french_text $date_du_jour
echo "Bon vol $USER"

exit 0

Astuce : Pour vous corriger, copier/coller le script, exécutez le et comparez.


Félicitation vous avez terminé le TP2 ! Vous pouvez passer au suivant, le TP #3.