Sommaire
- Remplacements
- Minimum et maximum
- Créer une corbeille
- Deviner un nombre
- Nombre de fichiers et de dossiers d'un répertoire
- Nombres aléatoires pairs
- Numéroter les lignes d'un fichier
- Expressions régulières
- Outil de terminal serveur
- awk : taille moyenne, nombre de fichiers
- Jeu type Motus
- Messagerie instantanée
- Tracer une courbe
- Affichage de fichier
- Erreurs à corriger
- Quizz sur les étapes d'interprétation
- Analyse d'un fichier avec awk
- Analyse d'un fichier avec sed
- Jeu de nim
- Procesus
- Chat avec interface Graphique
Remplacements
Objectifs : Manipuler les chaines de caractères, comprendre la notion d'entrée et de sortie standard
Durée : 5min
Difficulté : Facile
Consigne
Ecrire une commande qui permet d'écrire le résultat d'une commande echo dans un fichier texte en remplacant tous les espaces qu'il contient par des _
echo 'un texte' | tr ' ' '_' > ./fichier.txt
Minimum et maximum
Objectifs : Manipuler les principales structures, effectuer des comparaisons
Durée : 30min
Difficulté : Moyen
Consigne
Créer deux fonctions : la première cherche et affiche le minimum d'une liste de nombre passée en paramètre. La deuxième affiche le maximum.
#/bin/ksh
# Cette fonction permet de factoriser le code des fonctions
# de calcul du min et du max
function recherche {
res=$1
for nombre in $*
do
(( $nombre $symbole $res )) && res=$nombre
done
echo $res
}
# Cette fonction affiche le minimum de la chaine en paramètre
function min {
symbole='<'
recherche $*
}
# Cette fonction affiche le maximum de la chaine en paramètre
function max {
symbole='>'
recherche $*
}
# Cette fonction affiche le minimum de la chaine en paramètre
function min {
echo $* | tr ' ' '\n' | sort -n | head -1
}
# Cette fonction affiche le maximum de la chaine en paramètre
function max {
echo $* | tr ' ' '\n' | sort -n | tail -1
}
Créer une corbeille
Objectifs : Créer des fonctions, Manipuler les fichiers
Durée : 30min
Difficulté : Difficile
Consigne
Le but de cet exercice est de réaliser un mécanisme de corbeille qui permet de supprimer un fichier et de le restaurer. Pour cela :
- Créer une fonction del qui permet d'archiver le fichier passé en paramètre dans un dossier que l'on appelera la corbeille et qui surppime le fichier.
- Créer une fonction undel qui restaure le fichier archivé et qui supprime l'archive de la corbeille.
- Créer une fonction listdel qui liste les fichiers de la corbeille.
- Créer une fonction purgedel qui vide la corbeille.
#!/bin/ksh
# Emplacement de la corbeille
corbeille=/tmp/$USERNAME/corbeille
# Cette fonction permet d'archiver un fichier
# $1 chemin complet du fichier à archiver
function del {
[[ ! -e $corbeille ]] && mkdir -p $corbeille
[[ -e $1 ]] && tar -cvf $corbeille/$1.tar $1 && rm -r $1
}
# Cette fonction restaure un fichier
# $1 nom du fichier à restaurer
function undel {
if [[ -e $corbeille/$1.tar ]]
then
tar -xvf $corbeille/$1.tar
rm $corbeille/$1.tar
fi
}
# Cette fonction liste les fichiers de la corbeille
function listdel {
ls $corbeille
}
# Cette fonction vide la corbeille
function purgedel {
for fichier in $(ls $corbeille)
do
rm $corbeille/$fichier
done
}
Deviner un nombre
Objectifs : Manipuler les principales structures, effectuer des comparaisons, lire l'entrée standard
Durée : 30min
Difficulté : Moyen
Consigne
Créer un jeu qui permet à l'utilisateur de deviner un nombre compris entre 0 et 100 en effectuant moins de 10 propositions. Pour chaque proposition, le système indique à l'utilisateur si le nombre qu'il a proposé est trop petit ou trop grand.
(( alea = $RANDOM % 101 ))
i=1
echo "Essayez de deviner le nombre (entre 0 et 100)"
while [[ $i -le 10 ]]
do
read proposition
[[ $proposition -lt $alea ]] && echo trop petit
[[ $proposition -gt $alea ]] && echo trop grand
[[ $proposition -eq $alea ]] && echo Gagne && exit 0
echo "Essayez encore"
(( i++ ))
done
echo "Perdu ! le nombre etait $alea"
Nombre de fichiers et de dossiers d'un répertoire
Objectifs : Manipuler le FileSystem, itérer sur des fichiers
Durée : 10min
Difficulté : Facile
Consigne
Réaliser un script qui permet de compter le nombre de fichiers et de répertoires dans un répertoire donné. Le résultat est affiché dans la sortie standard
#/bin/ksh
repertoire=$1
nbRep=0
nbFic=0
for element in $repertoire/*
do
[[ -d $repertoire/$element ]] && (( nbRep++ ))
[[ -f $repertoire/$element ]] && (( nbFic++ ))
done
echo $nbRep repertoires et $nbFic fichiers
repertoire=$1
ls -l $repertoire | grep '^d.*' | wc -l
Nombres aléatoires pairs
Objectifs : Manipuler les principales structures, faire des calculs
Durée : 15min
Difficulté : Facile
Consigne
Réaliser un script qui permet de générer dans la sortie standard 20 nombres aléatoires pairs. Indication : la variable $RANDOM contient un nombre aléatoire
i=0
while [[ $i -lt 20 ]]
do
alea=$RANDOM
(( $alea % 2 == 0 )) && echo $alea && (( i++ ))
done
Numéroter les lignes d'un fichier
Objectifs : Lire l'enstrée standard
Durée : 15min
Difficulté : Moyen
Consigne
Le but de cet exercice est de numéroter les lignes d'un fichier qui est lu dans l'entrée standard. Il y a deux facons d'appeler le script : soit le nom du fichier est pris en argument soit l'entrée standard est utilisée.
#!/bin/ksh
# Cette fonction permet de numéroter les lignes lues
# dans l'entrée standard
function numeroter {
i=0
while read a
do
(( i++ ))
echo $i" "$a
done
}
if [[ $# -ne 0 ]]
then
numeroter < $1
else
numeroter
fi
function numeroter {
awk '{print NR" "$1}';
}
Expressions régulières
Objectifs : Comprendre la syntaxe des expressions régulières
Durée : 10min
Difficulté : Facile
Consigne
Donner le motif qui correspond à une adresse IP. Une adresse IP est de la forme suivante : 255.255.0.1 ou bien 127.0.0.1, son format est donc le suivant : Un à trois chiffres, point, un à trois chiffres, point, un à trois chiffres, point, un à trois chiffres.
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
Consigne
Donner l'expression régulière qui correspon à une date sous la forme « 29 février 2012 ». Une date au format 29 février 2012 suit le motif suivant : un ou deux chiffres, un espace, un nombre indéfini de lettres, un espace puis quatre chiffres.
[0-9][0-9] [a-z][a-z]* [0-9][0-9][0-9][0-9]
Outil de terminal serveur
Objectifs : Utiliser le système de fichier, manipuler les principales structures, gérer les droits
Durée : 1h
Difficulté : Difficile
Partie 1 : le client
Nous allons créer un outil permettant à une utilisateur connecté sur un poste de travail A d'exécuter des commandes sur un poste de travail B. Pour cela, on commence par créer un dossier partagé dans lequel les informations seront échangées.
- Le client attend les instructions de l'utilisateur
- Une fois une instruction entrée, il créé un fichier contenant la commande a éxécuter dans le répertoire d'échange (fichier nommé actions_<idep>.ksh)
- Le client se met en attente du fichier reponse_<idep>.txt
- Une fois ce fichier arrivé, le client affiche son contenu et le supprime
- Enfin, il se remet en attente des insctructions de l'utilisateur
#/bin/ksh
dossier_echange=/net/S50F-KSH-GGA/Users/k0b6qu/Desktop/echange
ident=k0b6qu
while read commande
do
echo $commande > $dossier_echange/actions_$ident.ksh
while [[ ! -e $dossier_echange/reponse_$ident.txt ]]
do
sleep 1
done
cat $dossier_echange/reponse_$ident.txt
rm -f $dossier_echange/reponse_$ident.txt
done
Partie 2 : le serveur
- Le serveur attent qu'un fichier actions_<idep>.ksh soit créé dans le répertoire d'échange
- Une fois que ce fichier est créé, il exécute la commande contenue dans ce fichier, et enregistre le résultat de la commande dans le répertoire échange sous la forme : reponse_<idep>.txt
- Il supprime le fichier actions_<idep>.ksh et se remet en attente de ce fichier
#/bin/ksh
# Emplacement du dossier partagé
dossier_echange=/net/S50F-KSH-GGA/Users/k0b6qu/Desktop/echange
# Identifiant des fichiers à traiter
ident=k0b6qu
# Fonction permettant de traiter une commande dans le fichier
# texte $dossier_echange/actions_$ident.ksh
function traiter_commande {
reponse=$dossier_echange/reponse_$ident.txt
$dossier_echange/actions_$ident.ksh > $reponse 2>&1
rm -f $dossier_echange/actions_$ident.ksh
}
commande=$dossier_echange/actions_$ident.ksh
while true
do
[[ -e $commande ]] && traiter_commande
sleep 1
done
awk : taille moyenne, nombre de fichiers
Objectifs : Utiliser awk, rediriger l'entrée standard
Durée : 30min
Difficulté : Difficile
Consigne
Déterminier avec awk la taille moyenne et le nombre de fichiers d'un répertoire donné. Le script awk à écrire sera placé derrière la commande ls -l.
BEGIN{
i=0;
n=0;
}
{
n=n+$9;
i=i+1;
}
END{
printf "%d fichiers\nTaille moyenne : %.2f\n", i, n/i;
}
Jeu type Motus
Objectifs : Utiliser les structures, lire l'entrée standard, manipuler les chaines de caractèrs
Durée : 1h30
Difficulté : Difficile
Consigne
Réalisez un jeu qui permet à l'utilisateur de découvrir un mot comme dans motus:
- Le système affiche uniquement la première lettre du mot et remplace les autres lettres par des «_». Exemple avec le mot MAISON : M _ _ _ _ _
- Le système propose alors à l'utilisateur d'entrer une propostion.
- Le système compare la proposition de l'utilisateur avec le mot mystère, toutes les lettres de la proposition qui sont bien placées sont alors affichées : par exemple M _ I S _ _ et le système propose alors à l'utilisateur d'entrer un nouveau mot.
#
# Ce script permet de lancer un jeu "Motus"
# Parametre 1
# Le mot à trouver
#
# La chaine de caractères à trouver
atrouver=$1
#
# Fonction permettant de comparer une proposition à atrouver
# La chaine de caractères en_cours est actualisée par la fonction
# Parametre 1
# Proposition à comparer à atrouver
# Retour
# 0 si les chaines de caractères sont identiques
# 1 sinon
#
function verifier {
res=0
encours=$(echo $atrouver | cut -c 1)
i=2
while [[ $i -le ${#atrouver} ]]
do
l1=$(echo $atrouver | cut -c $i)
l2=$(echo $1 | cut -c $i)
if [[ "$l1" == "$l2" ]]
then
encours=$encours" $l1"
else
encours=$encours" _"
res=1
fi
(( i++ ))
done
return $res
}
verifier
clear
while true
do
echo $encours
echo "Entrez votre proposition"
read prop
clear
verifier $prop
[[ $? -eq 0 ]] && echo Gagne && break
done
Messagerie instantanée
Objectifs : Utiliser les structures, réaliser des sémaphores, accéder au système de fichiers
Durée : 1h
Difficulté : Difficile
Consigne
Réaliser une application de messagerie instantanée. Deux programmes tourneront en parallèle :
- le permier permettra d'ajouter une ligne saisie par l'utilisateur dans un fichier texte (en s'assurant qu'aucun autre utilisateur n'écrit dans le fichier texte)
- le second permettra d'afficher le fichier texte en le mettant à jour automatiquement lorsque celui-ci aura été modifié.
lastmodif=0
fichier_conversation=/dev/fs/D/messagerie/conversation.txt
while true
do
modif=$(ls $fichier_conversation -l | cut -d " " -f 9)
if (( $modif == $lastmodif ))
then
sleep 1
else
clear
cat $fichier_conversation
lastmodif=$modif
fi
done
fichier_conversation=/dev/fs/D/messagerie/conversation.txt
while true
do
read a
while [[ -e /dev/fs/D/samuelestlemeilleur/.LOCK ]]
do
sleep 1
done
touch /dev/fs/D/messagerie/.LOCK
echo "Julien dit: $a" >> $fichier_conversation
rm -f /dev/fs/D/messagerie/.LOCK
done
Tracer une courbe
Objectifs : Utiliser les principales structures awk
Durée : 1h
Difficulté : Difficile
Consigne
Le but de cet exercice est de tracer la courbe du cosinus dans une fenêtre shell comme dans l'exemple ci dessous avec l'axe des abscisses vertical : Pour cela, nous allons utiliser awk.

BEGIN{
pas=0.15;
borneinf=0;
borneSup=500;
multiplicateur=40;
for(i=borneinf;i*pas+borneinf<borneSup;i++) {
system("sleep 1");
x=borneinf+pas*i;
chaine="";
if(multiplicateur*cos(x)>0) {
for(j=0; j<multiplicateur;j++) {
chaine=sprintf("%s ", chaine);
}
chaine=sprintf("%s|", chaine);
for(j=0;j<multiplicateur*cos(x);j++){
chaine=sprintf("%s ", chaine);
}
chaine=sprintf("%s*", chaine);
}
else{
for(j=-multiplicateur;j<multiplicateur*cos(x);j++){
chaine=sprintf("%s ", chaine);
}
chaine=sprintf("%s*", chaine);
for(j=multiplicateur*cos(x); j<-2;j++){
chaine=sprintf("%s ", chaine);
}
chaine=sprintf("%s|", chaine);
}
print chaine;
}
}
Affichage de fichier
Objectifs : Créer une commande, manipuler le système de fichier, créer des options
Durée : 45min
Difficulté : Moyen
Consigne
Créer un script qui permet d'afficher un fichier passé en paramètre. Ce script reconnaitra les options suivantes :
- -n : les lignes seront numérotées
- -h nb : seules les nb premières lignes seront affichées
#!/bin/ksh
# Ce script permet d'afficher un fichier texte
# Options
# -n
# Numérote les lignes du fichier
# -h nb
# Affiche les nb premières lignes du fichier
# Paramètres
# paramètre 1
# Le fichier texte à afficher
echo $* | grep -q '\-n' && numerotation=ok
debut=$(echo $* | grep '\-h' | sed 's/.*-h *\([0-9]*\).*/\1/')
fichier=$(echo $* | sed 's/-n//;s/-h *[0-9]*//;s/ +/ /g;s/^ *//')
[[ ! -e $fichier ]] && echo Le fichier n\'existe pas >&2 && exit 1
# Cette fonction permet de numéroter les lignes
# de l'entrée standard
function numeroter_lignes {
i=1
while read l
do
echo "$i : $l"
(( i++ ))
done
}
commande="cat"
[[ ! -z $lignes_deb ]] && commande="head -$debut"
commande="$commande $fichier"
[[ "$numerotation" = "ok" ]] && $commande | numeroter_lignes && exit 0
$commande && exit 0
exit 1
Erreurs à corriger
Objectifs : Identifier les erreurs de développement
Durée : 20min
Difficulté : Facile
Maladresse 1
cat fichier.txt | grep '7:'
#Le pipe ne sert à rien, la redirection de l'entrée se fait sur un fichier et non sur un processus.
grep '7:' < fichier.txt
Maladresse 2
for f in $(cat file)
do
commande "$f"
done
#La commande cat permet de concaténer les fichiers, pas de les lire. Pour lire un fichier, on le place dans l'entrée standard
while read f
do
commande "$f"
done < file
Maladresse 3
if [ $S_ESPEXE = I ]
then
partage_ihm=Recette
else
if [ $S_ESPEXE = A ]
then
partage_ihm=Developpement
else
if [ $S_ESPEXE = S ]
then
partage_ihm=Integration
else
partage_ihm=Production
fi
fi
fi
#Le nombre de test à réaliser est trop important, le programme sera long à cause des boucles imbriquées, et on ne comprend pas facilement ce qui se passe. Il y a plusieurs facons de corriger les erreurs.
partage_ihm=Production
[[ $S_ESPEXE == I ]] && partage_ihm=Recette
[[ $S_ESPEXE == A ]] && partage_ihm=Developpement
[[ $S_ESPEXE == S ]] && partage_ihm=Integration
case $S_ESPEXE in
I ) partage_ihm=Recette ;;
A ) partage_ihm=Developpement ;;
S ) partage_ihm=Integration ;;
X ) partage_ihm=Production ;;
esac
Maladresse 4
ps -l | grep -v 'STATE' | awk '{print $2}'
#Awk permet de réaliser des filtres sur les lignes d'un fichier, il n'y a donc pas de raison d'utiliser un grep.
ps -l | awk '!/ *STATE.*/{print $2}'
Maladresse 5
admsnap activate -s $sess | grep hdiskpower | awk '{print $6}' | sed 's/\/dev\/r//' | sed 's/\.//'
la commande admsnap activate -s $sess est à remplacer par echo 1 2 3 4 5 /dev/r/hdiskpower12.1
#Trop d'instructions s'enchainent, et bien qu'il n'y ait pas d'erreur grossière, le temps de traitement est très fortement impacté.
admsnap activate -s $sess | grep hdiskpower | cut -d ' ' -f '6' | sed 's/\/dev\/r//' | tr -d '.'
# ou
admsnap activate -s $sess | awk '/.*hdiskpower.*/{gsub("/dev/r/", "", $6);print $6;}'
# ou
admsnap activate -s $sess | sed 's/.*\(hdiskpower[0-9]*\)\.\([0-9]*\)/\1\2/g'
Maladresse 6
cd $repertoire
while true
do
echo entrer le nom du fichier à afficher
read fichier
cat $repertoire/$fichier
done
# Le cd est inutile, et les paramètre doivent être entourés par des guillemets au cas où l'utilisateur entre un nom de fichier avec des espaces.
while true
do
echo entrer le nom du fichier à afficher
read fichier
cat "$repertoire/$fichier"
done
Maladresse 7
for f in $(ls *.txt)
do
cat $f
done
# *.txt est expansé directement, pas besoin d'utiliser de ls ou de echo.
for f in *.txt
do
cat "$f"
done
Maladresse 8
function f {
...
cd /dev/fs/D/dossier
}
# On ne réalise pas de cd dans une fonction pour ne pas modifier les informations du processus courant. Si on fait un cd, on restaure à l'état initial.
# Mais le mieux est sans doute de n'utiliser dans les fonction (et de manière générale) que des chemins absolus.
# Le cd est une simplification pour l'utilisateur, mais n'est pas indispensable dans les scripts.
function f {
...
rep_courant=$(pwd)
cd /dev/fs/D/dossier
cd $rep_courant
}
Maladresse 9
ls $dossier | head –1 | read var
# Le pipe vers la commande read ne fonctionne pas en kornshell sous SUA, certains shell acceptent cette syntaxe.
var=$(ls $dossier | head –1)
Maladresse 10
fichier="/dev/fs/C/fichier 1.txt"
ls $fichier
# Il ne faut pas oublier les guillemets autour de $fichier dans ce cas. Même s'ils protègent l'affectation, ils ne se retrouvent pas dans la ligne suivante
fichier="/dev/fs/C/fichier 1.txt"
ls "$fichier"
Maladresse 11
commmande | grep '..*' | wc -l
# L'option -c permet de compter le nombre de motifs intercéptés par grep.
commmande | grep -c '..*'
Quizz sur les étapes d'interprétation
Objectifs : Étapes d'interprétation de la ligne de commande
Durée : 20min
Difficulté : Difficile
Que se passe-t-il 1 ?
alias f="echo alias"
function f {
echo fonction
}
f
alias est affiché. En effet, le traitement des alias est antérieur à celui des fonctions, f est donc d'abord remplacé par « echo alias ».
Que se passe-t-il 2 ?
alias ls=ps
alias ll="ls -l"
ll
ps -l est exécuté. Les alias sont traités entièrement, tant qu'il existe un alias dans la ligne de commande, celui-ci est résolu.
Que se passe-t-il 3 ?
alias a=ls
function ls {
echo fonction
}
a
fonction est affiché. Lors de l'appel de f, l'alias est traité en premier, f est remplacé par fonction. Lors de la localisation de la commande a effectuer, fonction est trouvée dans la liste des fonctions en mémoire et est exécutée.
Que se passe-t-il 4 ?
function f {
echo a
}
alias a=ls
$(f)
Une erreur est générée, a n'est pas reconnu en tant que commande interne. Lors de la détermination du type de commande, le traitement des alias a déjà été effectué. Voir les étapes d'intérprétation de la ligne de commande.
Que se passe-t-il 5 ?
alias a=ls
var=a
$var
Une erreur est générée, l'intéprétation des variables se fait après le traitement des alias.
Que se passe-t-il 6 ?
alias a='$var'
var=ls
a
ls est exécuté.
Que se passe-t-il 7 ?
script1.ksh
echo script1
exit 0
Dans un autre script :
./script1.ksh
script1 est affiché dans la console
. ./script1.ksh
script1 est affiché dans la console et on sort de l'interpréteur.
Que se passe-t-il 8 ?
var1=ok
var2='$var1'
echo $var2
Les variables ne sont intérprétées qu'une seule fois, $var1 est affiché. Pour afficher le contenu de var1, on utiliserait
eval echo $var2
Dans ce cas, l'évaluation des variables est faite deux fois.
Que se passe-t-il 9 ?
script1.ksh
cd /
Dans l'invite de commande :
cd /etc
script1.ksh
pwd
pwd affiche /etc, le cd effectué dans Script1.ksh est fait dans un autre processus que le processus courant.
Que se passe-t-il 10 ?
var="> fichier.txt"
echo texte $var
texte > fichier.txt est affiché dans la console, La mise en place des redirections ne signifie pas que la redirection est lue sur la commande, la redirection est récupérée sur au moment du découpage de la ligne en mots, le symbole > est considéré comme un séparateur.si un > se retourve encore sur la ligne de commande au moment de la mise en palce des redirections, il n'est pas pris en compte comme le symbole de redirection mais comme un caractère quelconque. S'il n'est pas présent au départ sur la ligne, la redirection ne peut être mise en place.
Que se passe-t-il 11 ?
alias var='ok'
echo var
var est affiché, l'alias n'est remplacé que lorsqu'il s'agit d'une commande.
Analyse d'un fichier avec awk
Objectifs : Utiliser awk, traiter un fichier, utiliser les expressions régulières
Durée : 1h
Difficulté : Difficile
Consigne
A l'aide du fichier annuaire.txt suivant :
Prénom NOM Date-de-naissance Sexe Numéro-de-telephone
Georges TARTEMPION 12 02 1967 M 038898422524
Adrien DUBOUCHON 27 11 1938 M 0154896372
Ludwig SCHMILLBLEERCK 28 12 1957 M 0258459887
Antonio VAVILDA 16 05 1937 M
Hughes CARPETTE 08 11 1958 M 0123568629
J'en ai assez de ce travail fastidieux!
Dagobert ELOY 14 07 1947 M 0225415487
Anatole SUISSE 01 02 1965 n 4
Antonino SZWPRESWKY 16 05 8937 M 0298358745
Créer un script awk qui créé un annuaire au format html :
<h1>Annuaire</h1>
<p>
<b>Mr Georges TARTEMPION</b>
<br />
né le : 12/02/1967
<br />
tel : 038898422524
<br />
mail : georges.tartempion@insee.fr
</p>
Les lignes vides ou mal formés ne seront pas affichées.
awk '
BEGIN{
print "<html><body><h1>Annuaire</h1>";
}
/[A-Z][a-z]+ [A-Z]+ [0-9]+ [0-9]+ [0-9]+ M|F [0-9]+/{
printf "<p>\n<b>";
if($6 == "M"){
printf "Mr ";
}
else {
printf "Mme ";
}
printf "%s %s</b>\n<br />", $1, $2;
printf "ne le : %d/%d/%d\n<br />", $3, $4, $5;
printf "tel : %s\n<br />", $7;
printf "mail:%s.%s@insee.fr</p>\n", tolower($1), tolower($2);
}
END{
print "</body></html>";
}'
Analyse d'un fichier avec sed
Objectifs : Utiliser sed, taiter un fichier, utiliser les expressions régulières
Durée : 1h
Difficulté : Très difficile
Consigne
Même exercice que Analyse d'un fichier avec awk mais avec sed sauf la gestion des minuscules/majuscules (trop long pour être traité)
# Appel de sed sed -n -f commandes_sed.txt annuaire.txt
# Le script sed correspondant :
1, /[A-Z][a-z]* [A-Z]* [0-9]* [0-9]* [0-9]* [MF] [0-9]*/s!^!<html><body><h1>Annuaire</h1>!g
/[A-Z][a-z]* [A-Z]* [0-9]* [0-9]* [0-9]* [MF] [0-9]*/!d
s/\([A-Z][a-z]* [A-Z]* [0-9]* [0-9]* [0-9]* \)M\( [0-9]*\)/\1Mr\2/g
s/\([A-Z][a-z]* [A-Z]* [0-9]* [0-9]* [0-9]* \)F\( [0-9]*\)/\1Mme\2/g
s!\([A-Z][a-z]*\) \([A-Z]*\) \([0-9]*\) \([0-9]*\) \([0-9]*\) \(M[mr][e]*\) \([0-9]*\)!<p><b>\6 \1 \2</b><br />ne le : \3/\4/\5<br />tel : \7<br />mail : \1.\2@insee.fr</p>!g
p
Jeu de nim
Objectifs : Manipuler les chaines de caractère, manipuler les principales structures, lire l'entrée standard
Durée : 1h
Difficulté : Difficile
Consigne
Créer un script qui permet de jouer au jeu de nim : Quinze alumettes sont posées, chaque joueur à tour de rôle choisit de une à trois alumettes et les retire. Le joueur qui tire la dernière alumette a perdu.
- Créer une fonction qui permet d'afficher autant de « | » que d'alumettes restantes
- Au démarrage d'une partie le nombre d'alumettes est initialisé à 15 dans une variable alumettes_resantes.
- Créer une fonction qui permet de retirer de une a trois alumettes de ce nombre, le nombre à retiré est passé en paramètre
- Créer une fonction qui permet a l'ordinateur de retirer un certain nombre d'alumettes selon la règle suivante : une fois que l'ordinateur a joué, le reste de la division euclidienne du nombre d'alumettes restantes par 4 devra être 1. Si cela n'est pas possible, l'ordinateur prend 3 alumettes
#
# Fonction qui affiche autant de batons que d'alumettes restantes
# Parametre 1 : le nombre de batons à afficher
#
function afficher_reste {
i=0
a_afficher=""
while (( $i < $1 ))
do
a_afficher="| "$a_afficher
(( i++ ))
done
echo $1 alumettes restantes :
echo $a_afficher
}
#
# Fonction qui permet de prendre des alumettes
# Parametre 1 : nombre d'alumettes à prendre
#
function prendre {
if (( $1 < 4 ))
then
(( alumettes_resantes-=$1 ))
else
echo vous ne pouvez pas prendre plus de 3 alumettes
fi
}
#
# Fonction qui permet de faire jouer l'ordinateur
#
function jeu_systeme {
a_prendre=3
(( \( $alumettes_resantes - 1 \) % 4 == 1 )) && a_prendre=1
(( \( $alumettes_resantes - 2 \) % 4 == 1 )) && a_prendre=2
echo le systeme prend $a_prendre alumettes
prendre $a_prendre
}
#
# Fonction de lancement d'une nouvelle partie
#
function nouvelle_partie {
alumettes_resantes=15
while (( $alumettes_resantes > 1 ))
do
afficher_reste $alumettes_resantes
echo combien vous vous en prendre ?
read choix
prendre $choix
if [[ $alumettes_resantes -ne 1 ]]
then
sleep 1
jeu_systeme
(( $alumettes_resantes==1 )) && echo Vous avez perdu
else
echo vous avez gagne
fi
done
}
Procesus
Objectifs : Gerer les processus, utiliser les signaux
Durée : 1h
Difficulté : Difficile
Partie 1. Création du script
Créer un script qui incrémente une valeur toute les 5 secondes et affiche la valeur dans un fichier texte de sortie. Ce script peut être interrompu a l'aide d'un Ctrl+C, mais dans ce cas là, le fichier de sortie doit être supprimé. Lorsqu'une réinitialisation est demandée, le compteur repart à 0.
trap 'rm -f $sortie' INT
trap 'i=0' HUP
sortie=sortie.txt
i=0
while true
do
sleep 5
echo $i > $sortie
(( i++ ))
done
Partie 2. Lancement du processus
Lancez le processus en arrière plan et tester la réinitialisation et l'arrêt avec Ctrl+C (sans utiliser de kill).
./compeur.ksh &
kill -HUP %1 &
jobs
[1] + Running ./compteur.ksh
fg %1
Ctrl+C
Chat avec interface Graphique
Objectifs : Gestion des processus, appel de java, notion de sémaphores
Durée : 45min
Difficulté : Difficile
Consigne
Le fichier chat.jar contient une interface graphique qui permet de lancer une application de chat. Deux exécutables sont dans ce jar :
- AffichageFichier permet d'afficher la conversation ; le path vers le fichier contenant la conversation est donné en argument au programme.
- ChampTexte permet de demander à l'utilisateur d'entrer un texte. Lorsque le texte est entré par l'utilisateur, celui-ci est affiché dans la sortie standard. Je nom d'utilisateur est passé à l'aide d'un -DnomUtilisateur.
Ecrire un script shell qui permet de piloter ces deux applications pour réaliser une application de chat. Il faudra veiller à détruire tous les processus créés par ce script.
set -x
trap 'kill -9 $ancienPid; kill -9 $pidChampTexte; exit 0' INT KILL
fic=/home/messagerie/conversation.txt
> $fic_conv
java -DnomUtilisateur=Julien -jar ChampTexte.jar >> $fic_conv &
pidChampTexte=$!
nbLignes=0
while true
do
nb=$(wc -l < $fic_conv)
if [[ $nb -ne $nbLignes ]]
then
nbLignes=$nb
[[ -n $ancienPid ]] && kill -9 $ancienPid
java -jar AffichageFichier.jar $fic_conv &
ancienPid=$!
fi
sleep 1
done