.1' :'iiiî:E[i$:+
" : ": :
ffi{...îlTJ#ffiif; ilî:.,|$Ï farrta 2 : Commandes syslème et prograntmation Shell ,'i-;,11, "
1..'..,'
Excrcices corrisës
Labo Environnement UNIVLIl\trUX
Exercices corrigés en sheltr
163
l::';ll1:, 1 :.:,;!!; 1: i: :::::;:: portie 2 :'Cotanandes système et programmation Shell .. '.:' ]
. Exercices coriipés
VARIÀBLES ET EII\IIRONNEMENT
Exercice : ffir u*ir visualisé le résultat de la commande env (diverses valeurs de variables pnËdéfinies), écrire un script shell qui en affiche certains ainsi quccelles rclatives au script et ses arguments.
#sh1: script.affrchant Ia valeur de plusieurs ffuariablespédéfinies de I'environnement et du shell echo directory home : $HOME echo user bgname : $LOGNAME echo my mailbox: $MAIL echo path value : $PATH echo shell courmands : $SHELL echo terminal type : $TERM echo script name : g0 echo scriptpid: $$ echo arguqçts number : ffi. echolst of4rguments : g*
I t I
Exercice: Ecrire un sc"ffl>hell manipulant les quotes (simple, double et anti).
#sh2 : script nanipulânt
les guotes
var=exemple echo contermde var : $var echo "contenu de var : gvar" echo'contenu de var: $var'
echô ôèci enf-JYexemple type de l\apostrophe echo "ceci est I'exemple type de I'apostrophel
r65
.'"r,-
", Parte 2': Commaides
Exercice: Ecrire un script shell affichant la liste indiquant chaque fois sa classe
des caractères spéciaux en
#sh 3 : liste deb''caracières spéciaux du shell
echo les caractères spéciaux sont : \)" echo -e "\t les différentes quottes : \( \" \'\' echo -e "\t les parenthèses et assimilés \( \[ \] echo -e "\t les symboles de ponctuations : \( \' \: \; \)". echo -e "\t les opérateurs arithmétiques: \( \+ \' \* \/ \% \)" echo -e "\t les comparateurs : \( \> \< \= \! \ | \& \)" echo -e "\t les symboles spéciaux : \( \\
\? \@ \$ \- \)"
\) \( \{ \} \)"
Exercice : Ecrire un script Utilisant, diverses possibilités pour a{ficher le contenu d'une variable et affecter son contenu'
:
#sh4 : I'affectation varO="" ; echo varO : $varO varl=chaine ; echo varl : $var1 var2="une chaine" ;echo var 2 : ù"o^- ,na1g=gvar1 ; echo var3 : $var3 echo "variable non affeitée" ; echo var : $var echo "var est une chaiue vide" ; var="" var4-${var:valeurl} ; echo var4 : $var4 ; echo var : $var varS-$tvar;+valeur2) ; echo varS : $var5 ; echo var: $var var6-${var:-valeur3} ; eôho var6 : $var6; echo var: $var u"17=${var:="valeur4"} ; echo vat7 z $var? ; echo var : $var echo "var est une chaine non videll ; var="valeur" var4-g{var:valeurl} ; echovar4 i $var4; echo var: $var varS=g{var :+vai.eur2} ;-echô varS i $var5 ; echo vàr : $var var6=${var :-valeurS},; echo var6 : $var6; echo var: $var
; jii;i, ; : :il,*!iii-,i::' t;.,; ..1 , .;. ,
;t.:r..i;::;1
Shell
E-terciecs co
FICHIERS ET REPERTOIRES
Exercice : Ecrire un- script qui adnret un unique paranrètre optionnel devanl
le répertoire
indiqué, si celui_ci est valide.
Idans
rers qui sont inclus
#sh5 : script affichant la liste des fichiers # # #
inclus dans le répertoire clonné en paranrètre il s'agira dlr répertoire coul.ant si pls cle paranrètres il s'agira d'une er.r.errr si pir_rsieur.s paraurètres
if test $# -gt, I theu
echo errent ; tlop cle pat.amètres echo "us.age- : $PWD/$O [directorl,] "
elif test S# -eq 0 then
echo contenr.r clu t éper.toir.e conrant : l" $r
clif tcst -d $1 tl'ren
echo contentr du r.épertoire $l ls -l $1
elsc
fi
echo errenr : $1 nYc'st pas ul.r répertoire echo "rrsage : $PWD/$0 [dir.ector1,]"
rrI
I
Erercice : Ecrire un script qui adnret la spécilication d'un paranrètre et qui affichera pour chaque fichier qu'il Un total par tyPe de t'ichiers sera égalenrent affiché.
répertoire conlme renfernre son type.
nbficSpc='expr $nbficspc + l.
echo gi inconntr
else
fi done
#sh6: 4 t
4 r
script affichant Ie type de chaque fichier appartenant au répertoire passé en paranrètle ainsi que Ie total par catégorie trcuvé
iftest $# -ne 1 then
echo erreur : un llaramètre est atlendtt echo "usage : $P!VD/$O directory"
elif tesr -d $1 then
nbficOrd=0 nbficReP=g nbficSpc=0
cd $1
fori in* do
iftest -d $i ihen
echo $i est ttn fichier répertoire nbficReP='s)itt $nbfrcRep + 1'
elif test -f Si then
echo $i est un fichier ordinait'e bficOrd='expr $nbficOrd + t'
elif.(ls $i) 1> laevlnutt then '
echo $i est Lrn fichier sPécial
l o8
echo nombre total de tîchier. r.éper.toire : gnbficRen echo nombre total de fichier ordinaire : $nbficOrd echo norubre total de fichier spéciaux : gnbficSpc
else
echo gl nYest pas un réper0oire
II
Exercice : Ecrire un script qui affiche ra risre des sous répertoires d'un ou prusieurs 1é9e1oir91 qa_ssés en paranrètres, ainsi que leui toral. On testera'à.tuqr. fois la validité du répertoire passé en paiamètre.
#sh7 i script lisiant les sous.répertoires du (des) répertoire(s) # passés en paramètre d'appel ainsi que leur tàtal ge"èih
p1p=.pwd. if test $# -eq 0 then
echo erreur : paranrètres manquants echo "usage : gPWD/gO directory...,f
- else
for i in g* do
echo if ! test -d gi then
echo erreur:
$i n\est pas un répertoire
else
cd $i Total=0
':,.; ''
PanÏe2:CommandesstsièmeaPioà|ammatlonShell!Exerclcescorrlgës :r!:-''::
':-;':
,-,ll]5l
I I ' utho liste des sous-répertoires de $i :
--
-l-'.r,
forj in * <io
if test 'd $j then
, ,
, I
fi
echo $j rl,otal='expr $Total + 1'
clone echo "Total = $Total"
done
cd $DIR : restibution du chemin initial echo --------'
Exercice : En recourant à Ia commande find écrire un script répondant aux besoins â;ufn"f,ug" de la liste des sous répertoires soit dù répertoire courant si aucun Daramètre n'est précisé ou du répertoire donné en paramètre'
#shS : pareil que sh? #
ii.t. d., sous-répertoires de celui passé en paramètre
if test $# -gl 1 tl'ren
echo erreur : nombre de paramètres importants echo usage : $O ldirectorY]
else
if test $# 'eq 0 then
d.osbier=;-
#r-épërtôirê cotirant,
else
.
dossier=$1 #répertoire passé en paramètre
"
tîe 2 i Commandes
fi find $dossier -type d -print
i
Exercicé : Ecrire un script récursif qui affiche le contenu d'un répertoire passé en paramètre dont la spécification de clremin doit au préalable être validée.
: r, #sh9 : script affichant récursivement le contenu d'un répertoire passé en paramètre
#
if test $# -ne 1 then
echo erreur echo "usage exit
tr if ! test -d $1 then
un seul argument est uôcessaire $0 directory"
echo erreur echo "usage
$1 nYest pas un répertoire $0 directorv"
else
echo "" i echo "----i'----.--.-- for j in Ê1t'* -- do
"'
répertoire : $t --------.------
iftesr -d $j then
traitement du sous répertoire $0 $j
, # appel récursif
else
eciro $j
done
Parlie 2 : Commandes système et Programmatîon Sh;U
Exelcices'corrigéE
;:'.:ti i;portit z t Co m ma n d es
Shell
Exercices
Exercice: Ecrire un script qui utilise les définitions d'environnements que I'on peut empiler et dépiler moyennant le parenthèsage pour afficher récursivement .le contenu d'un répertoire passé en paramètre
t$crire un script qui admet en ordinaire ou répertoire. (sinon il résultat ses l0 premières lignes.
entrée un paramètre de type fichier s'agit d'une erreur) et affiche comme
#shgbis: script affichant récursivement le contenu d'1rn répertoire pasSé en paramètres # #nota : agit comme ls -R J+î
on utilise pour chaque sous répertoire un environnement d'exécution qui lui est propre et obtenu par les fameuses parenthèses !
J1 t 11î
eChO -e'r\n\n=:=débUt=---======== if test -d $1 then
$
( #empilement d'un nouvel environnement
for i in $1/* do
if test -d $i then $0 $i#appel récursifcar $i est un répertoire else
ls $i 2>/dev/null if test $? -eq 1 then echo "répertoile vide"
done
) f*dépilement d'environnement
#sh 10 :
script visualisant les 10 premières lignes du
contenu d'un fichier ou d'un répertoire passé en paramètre
if test $# -gt I then
echo erreur: trop de paramètres echo usage : $0 lichier \ | répeertoire exit
fi if test $# -eq 0 then
echo erreui : paramètre obligatoire echo usage : $0 fîchier \l répertoire exit
1r'
if test -d $1 -a -r $1 then
i..
echo "------ contenu partiel du répertoire $l ------_ ls -l gt I head -10
:' elif test ,f $l -a -r $1 , then
echo "++++ contenu partiel du fichier 91 +++++" he ad -10 $1
echo ":::::: répertoire ou fichier non accessible :::::,,
173
p a n i e i i co:i;;;t"'#t$i
et
liste de noms de fichiers'admis en paramètres d'entrée. Le script devra vérifier que la donnée n est correcte et il en est de même avec les fichiers.
#sh10bis : script visuaiisant les n premières Iignes (par défaut = 5) d'une liste de fichiers # les paramètres de ce script sont n et les fichiers #
if test $# -lt 1 then
echo erreur : paramètres attendus echo usage : $0 [nbrelignes] Iichier... exit 1
tl
if (((expr $1 + 1) l>/dev/null) 2>/dev/nu11) then
if test $1 -Ct 0 then #un nbre de lignes est précisé
n=$1 shift
else
fi
echo "erreur : nombre incorrect" echo usage : $0 [nbrelignes] fichier'.. exit 2
else
fi
n=5 #valeur prédéfinie
if test -z $1 then
èôh6 "erreuf :'unè liste de fichier est attendue" echo usage.i $0 [nbrelignes] fichier... exit 3
fi
..----- - -'
t''
,.
.. .. . ., , r i-,
head -$n $p 2>/dev/null if test $? -eq 1 then
echo -e "\t Aucun fichier de ce nom !!!,'
fi
echo -e "\t $p n'est pas un fichier !!!"
else
{i
r ,'"
- .-.J- - -:.- .-- -
I
Publicité
_ . -. '
-ri _:t::::
._
- :r.ir.
-!:i:- -:* :
- ir .;,l -1 .. -'
'ir. " r t:
t,5i fi
:i
i
Panie 2 : Commandes systèry94i2y9g1gymg1ptt Shell
Exercices corrigés
i,Poat,2 , 3!-!non4!!
DU CALCUL ARITHMETQUE
Exercice : Ecrire un script qui indique si une donnée lue à partir du clavier est de type entier ou chaîne de caractères
#shl1 : #
script pour commencer du calcul
vérifie si la donnée lu est un décimal
echo "ce script reconnaît si une donnée est un entier ou pas" echo "== echo -e "introduire une donnée : \c" read val
echo -e "...-.-...'... analyse de la-donnée : \c" if ((expr $val + 1) 1> /dev/null ) 2> /dev/null then
echo c\est un entier
else
fi
echo c\est une chaine de caractères
;'prod=1 ,-while ! test -z $1 ido
som='expr $som + g1' prod='expr gprod \* $1' shift
done
expr gsom / gnbr'
ril.lti,îi:
r
,...,;..æ gcho "Iiste à traiter : gliste" ' i echo "taille de cette liste = $nbr', , ,., echo "somme de ces nombres = $som,. .: echo "produit de ces nombres.= $prod,, .: echo "moyenne de ces nombres - $-oy',
qui réalise les divers calculs arirhmétiques simptes t.il,.ï,jl.1:ril, ,rç;,1lf"t_tlt"t,la connaissance d'un première opérande, d'un opérateur et rï d'un second opérande..on vérifiera que tes opérandes sont bel;t bien des et que les opérateurs pàr-i :+,_ (opérateurs additifs) ,x.t (la anoT9..r: ' $.grultinlication et la division) et %(modulo).
lont
Exercice: Utilisez la comman.Jc case pour écrire un script qui admet en entrée plusieurs entiers et qùl aeterminera leur somme, produit et moyenne. La liste des entiers est de taille quelconque.
#sh12 : calculons la somme, le produit, la moyenne d'une liste de nombre donnée en paramètres # #hypothèse ;-on ne vérifiera pas qu'il s'agit de nombres
liste=$@ nbr=g#
calcul arithmétique simple du style 5 + ? trois paramètres sont attendus : op.l oper op2
.#d'abord un tgst sur les paramètres if test $# -ne B
echo erreur dans l\expression echo usage : $0 opérandel opérateur opérande2 echo attention : la multiplication est rËprésenti par x
-- bxit 0
n99i!9 un calcul équ!v4-19-nt à çxpr $t $2 $g vec vérification préalable des opérandes
176
-
111
ll
!i ii l,'i l;l l.r i: I i. ,
Iil'gi Ii
i l l
lil Iif
iill
.,,
. i. :.
.. it, :.
#puis des opérateurs parmi '' +, ', *, I et Yo if (((expr $1 + 1) 1>idev/null) 2>/dev/null) then
if (((expr $3 + 1) l>/dev/null) 2>/dev/null)
then '^'" "iÏï{i'i,*3;i
'/') if test $3 -eq 0 then
echo erreur : divison par zéro
else
fi;;
expr $1 / $3
'olo') expr $1 % $3;; *
) echo erreur : opérateur inconnu ;;
esac
echo erreur : 2d opérande non numérique
else
fi
else
echo erreur : 1er opérande non numérique
?r
'
Exercice : Ecrire un script de calcul itératif de commande while ou until. On ne traitera de capacité.
I
la factorielle en utilisant la les problèmes de dépassentent
#sh14 : # if test $#'-ne 1
calcul de la factorielle itérativement le paramètre doit être un entier positif
'---'then - echo "erreur : façtorielle de quoi ??" - ;___:-el!f l_(((9xp1 $1 t .1) 1> {4ç"1""10" |> /dev/null) ;:, i, then 1.' QcJro "erreur : paramètre,iton nombre" . r 'fi:l|.t:'_tql,:lt 0 'i - ',in ' '1,+ii;;,' *;?ffiffis
eiho "erreur : factorielle d'un nombre néeatif' fact=1 n=S1 until test $n -lt t do i t
f".t='expr gfact \* $n' n='expr $n - 1'
done echo factorielle\($1\) = gfaci
Exerclce : Ecrire un script shell utilisant le concept de fonction récursive pour calculer la factorielle d'un nombre.
#sh15 : factorielle récursivement #
et de plus avec un sous progr.amme (une fonction locale)
function factorielleQ t if test $1 -eq 0 then
return I
else
fact='expr $Z \* tt' n+'expr $1 - 1' factorielle gn gfact #appel récursif avec n-1 et la factorielle précédente
n )
:.'' #programme principal -*:i echo -e'\t\t CALCUL DE LA FACTORIELLE" .::-'. gghg :ri l
=========================,1
-è !\t\t
.":.. I l!.., r;:r,-(,!;
:i1,:: e
on suppose que I'entier est positif ou nul
UTILISATEURS
fact=1 È?ToiGue glvur $gEl # appel de la fonction avec deux arguments : # - iact étant le germe initialisé à t et devant contenir # # - Nbi est l'entier pour lequel on cherche à calculer la #
Ie résultat finai
factorielle
echo -e "\t résultat de factorielle($Nbr) = $fact \n"
Exercice : ffiEilt.ript
récursif pour le calcul de la factorielle d'un nombre.
#sh 16 : Ia factorielle récursive #attention : ici on ne vérifie pas les erreurs sur les données
if test $1 -eq 0 then
echo 1
else'
#on décrément n n='expr $1 - 1' #on calcule n x factorielle(n -1) echo'expr $r \* $($0 $n)' # rappel : # # #
$0 est Ie nom du Présent scriPt $1est I'argument d'appel qui vaut à chaque fois
Ie résultat de I'expression n:= n - 1
' # do.tc Ia Commande ci.dessus est équivalente à
un appel recursifdu ltYle :
fact(n);n * fact (n- 1)
'
fi
i
Ii t. f, l : I l'
i 1l F: t, f;
l!
;t
t' t' ii [':
li
î_! .t' it li
Exercice : Ecrire un script qui, étant donnée le nom d'un utilisateur, renseignêra sur I'appartenance de cet utitisateur au système et s'il ést acttiellem"nr connecté.
#sh 17 : t+r 1+tr
script vériliant si un nom d'utilisateur fait partie des utilisateurs du système et s'il est connecté au svstème
echo.e "\n\t\t RENSEIGNEMENT UTILISATEUR " gChO -e " \ *rl
==================----------
\t\t
echo -e " \t donnez un nom d'uilisateur : \c', read nom
cat /etc/passwd I cut -f I -d ":" I grep gnom >/dev/null case $? in 0) echo 'e "\t gnom : fait partie des utilisateurs de ce système" if who I cut -f 1 | grep gnom >/dev/null then
echo -e "\t\t et il est en ce moment connecté \n,,
- else
echo -e "\t\t mais il est absent en ce moment \n,,
fi'
r)'fcho -e'l\t $nom : n'est pas connu de ce système !!! \n,,
,t
esac
Exercice: Le script:à-èôriie-admet deui paramètres : le nom d,un nom lichier conrenanr uh tèxte imprimable. Il doit : '
!:ll vérifierla validité de ses paramètrei;
utilisateur et le
-- tgo
.1 81 .
i i i.::l ::*l:
:^ i :
iriri et
décider d'envoyer le fichier à ra boite aux lettres de l'utitisateur ou rJ lui afficher direcrement sur son écran seton que |utirisa"ri .ri, actuellement connecté ou pas et en fonction de son etrt o'uc..piàtùi de messages en ligne ou pas.
I
4
#sh1B : script qui, étant donné un nom d'un utilisateur et d'un message dont le contenu est défini dans un fichier donné, se propose de faire parvenir le message à I'utilisateur soit par envoi direct sur sa boite au lettres soit directement sur son écran
1+
J+
suppose que la commande mail est accessible
#on
echo -e "\t\t ENVOI POSTAL' eChO -e "\t\t =-=-========= \n" echo -e "\t introduire le nom du destinataire r:ead dest echo -e "\t introduire I'emplacement du paquet à envoyer : \c,' read paq
cal /etc/passwd I cut -f 1 -d ":,' I grep $dest >/dev/rtull case $? in
0)
if ! test -f $paq then echo "ERREUR : nom de fichier incorrect" elif then echo "message affiché sur l'écran de $nom" else
write gdest < $paq D/dev/null
.mail gdest < $paq D/dev/null case g? in 0) echo "message envoyé à la boite aux lettres',
L) echo "pas de boites aux lettres trouvé !!" ,ii esac
--
1)
tr ,, echb'TERREIIR : utilisateur inconnu d.u àystème"
.. .
tt
'
LISTE DES PARAMETRES
'Éxercice : Ecrire u,n script shell permettant des ses iraramètres effectifs.
I'affichage de plusieurs façons de la Iistc
#sh$ : sript obtention des paramètres d'un script
echo nom du script: $0 echo nombre d\arguments d\appel : $#
iftest $# -eq 0 then
echo liste de paramètres vide
else
echo liste des paramètres obtenus par \g* : g*
echo liste des paramètres obtenus par \g@ ; $@
echo "liste des paramètres
affichés par une boucle for : "
for i do i done
echo -e "gi \c"
echo "\nmême liste obtenue par une boule while :', while test $# -ne 0 do
echo -e "91 \c" shift
done
.!
,-i
-: :r '-l.r
;\ '. :
i'i:: i
!' ,- ;
:! - 'l: :, :.
. iitt . : .r :
-i-
.. -
, :
Partie 2 : Càmnandes syslème et programmatiott SlJell
E*ercices corrigés
Exercice : En recourant à la commande cut et un fichier temporaire contenant initialement la liste des paramètres, écrire un script shell qui construit une liste inversée de ces paramQtres avant de les afficher dans cet ordre. On suppose que la liste des paramètres effectifs est de taille quelconque'(et donc au delà de 9).
#shl9bis:
4 tt
script pareil au sh19 avec plusieurs variables
if test $# -eq 0 then
echo nombre de paramètres égal à zéro
else
echo liste des paramètres : echo -e
u\t $t"'
#construction de la liste echo $@ > tmp.tmp n=$# until test $n -eq 0 do
lisgs="$Iiste'cut -f$n -d" " tmp.tmp"' n='expr $n - 1'
done rm -f tmp.tmp #fin constructipn
echo liste inversée : echo -e "\[ $]isf,s"
Publicité
fi
SIMULATION MSIDOS
Exercice : Ecrire un script shell qui peut interpréter les commandes internes de MS/DOS et en particulier: copy, cls, date, del, dir, exit, more, ren, time, rype. Remarques: - Les commandes peuvent être minuscule ou en majuscule.
introduites en
indifféremment
- On devra respecter également la syntaxe de ces commandes et leurs
options, par exemple : DIR [P | /W] [chemin].
script des commandes internes de MS/DOS
interpreter Q I t case $1 in lCcllLUlSsl ) lcclloollPpltYyl)
. clear;;
if test x$3 = :ç then cp $2 $HOME/. else cp $2 $3 fi;;
tDdllAallTtllEel) date *"Yoa%oD";; tDdltEel[LU ) tDdltliltRrl) if test x$2 = x
rm -f g2;;
then ls
. else case $2 in
,,
':-.
'7p" | '7P') if test x$3 = i
then ls I more else ls $3 | more
fi;; :_ . jllWll | ,'/W1) if test xg3 = x
:'-----
-:
then ls elsels$3
184
fi;;
then ls $2
t 85
:!i:..à-:...>rl,ji.-
,: ,:r ,:t :;. .i . else echo option $2 inconnue
fi..
fi;;
MmllOollRrllEel) [Rr][Ee][Nn] ) [rt][Ii][Mm][Ee]) lrtl[Yy] [Pp][Ee])
*)
cat $2 | more;; mv $2 $3;; date *"%T";; cat $2;; echo commande incorrect;;
esac )
##
function menuQ t whiie true do
echo -e "\tDOS>\c" reacl commancle set $commande if test zzz$I t= zzz then
case $1 in
tEeltxxlllillTtl )
fi """.
l
done )
ciear echo -e-"\t\t DOS COMMANDS ' eChO -g "\t\t---===========\n" mènù- -
clear; break;; $*;;
.interPreter
186,i ;;,
,'t :.1 et
Eiercices
PROCESSUS & SIGNAIIX
fd1
tii
Exeicice: ' j .signal par la commande kill nécessite la L'envoi d'un quelconque connaissanbe du numéro du processus signalé. On désire écrire un script. qui tue un processus connu par son nom (paramètre d'entrée à vérifier au préalable)'
#sh21 : #
script qui étant donné ie nom du processus
lui envoie le signal SIGKILL pour le tuer
iftest $# -eq 1 then
#obtenir avec ps de la ligne contenanl le nonr nu='ps I grep $t' #découper cette ligne en plusieurs chanrps set $nu #premier champ = numéro de processus kill -9 $1
else
fi
echo erreur : paramètre attendu echo usage : $0 NomProcessus
Exerclce : Ecrire un script permettant de détruire un ensenrble de processus dont les noms sont passés comme paramètres d'entrée au script.
..#sh22 :
#
,i. . ij ..-
script détruisant une liste de processus dont les noms sont donnés en paramètres
',r! if test $# -eq 0
FI lÉl:i
|{ i.
Partîe 2 : Comntandes système et programmatîon Slrell
Exercîces corrigés
echo usage : "$0 process..."
else
for i in $" do #on suppose que les sorties de ps sont de
#la forme : # # # #on utilise cut avec comme délimiteur "p"
TIME CMD PID TTY 500 pts/O 00:00:01 bash 'cat 6L5 pts/O 00:00:00
' #ce n'est pas fameux mais ?!! . pid='ps I grep -e $i I cut -fl -d "pu'
if tesr $pid then
t<ill -9 $pid
else
echo $i : processus inexistant
.
fi done
fi
Exercice : gcrire un script qui affiche le nom de chaque sous répertoire appartenant au répertoire donné en paramètre (par défaut le répertoire courant) puis lit au terminal'une commande qu'on exécutera sous le sous-répertoire affiché. L'exécution de la commande, lorsqu'elle est valide, ne doit pas être interrompue (par un CTRL-C)
#sh23 : script qui affiche le nom de chaque sous répertoire # appartenant au répertoire donné en paramètre (par défaut # il s'agira du répertoire courant) puis exécute dans ces sous' - =# répertoires une commande qui sera introduite au terminal
-.
if then
elif
test $# -gt 1
echo I'erreur : trop de paramètres" test $#.eq 0
then elif then
"orrr"p1='pwd' test .d $1 if test "$1" = ".' then courant-'pwd' else courant=$1 fi
else echo "erreur : Auncun répertoire de ce nom"
exit 1
fi
echo -e "\l ====== liste des répertoires de $couranf, =====. nbrep='6nd $courant -type d -maxdepth 1 lwc -l'
if test $nbrep -eq 1. then . echo "pas de sous répertoires dans $courant',
exit 2 ls -l gcourant I grep "^d"
.,,. else 'ïii; {i
:
cd $courant
€cho -e "\n\n\tCommande à exécuter, e)uitter, ?)help:\n"
.i i i
:. for dir in * +r do r;' iftest -d $dir .:.: then .,i:, echo -n "$dir => " trap 'clear ; exit' 2 .; :. read cmde ', case $cmde in rrt\ ij , '' ,r
€cho
tt "
ti
:' '' ,
,.!
t t
taql)
clear exit 0
',, ,-.. _:
t88
18 9
Partie 2 : Commandes
.. :l:r)'1;r et Dro.
? l
")
lHhl[Ee][Ll]tPpl) echo "ce script vous facilite la réalisation" echo "d'une commande que vous saisissez " echo "sur un répertoire qui vous sera précisé" echo "parmi ceux du répertoire courant ou" echo " celui que vous allez donné en paramètre" exit 3 t;
if trap : 2 ; eval $cmde $dir b/dev/null then
echo "\n"
echo "erreur : commande inconnue ou erronée"
else
fi
esac
fi
done
Shell
Exercices
COMMANDE EVAL
,:':".. Exercice:- ,::-lri',Ecrire ur1 script.Qui affiche.-ses paramètres données dans |ordre inverse r,i .d!-]l].1_ipl..rl,i:i..On. utitisera pour cela la commande eval et on construirâ au préarable ra riste inversée. on suppose que Ie nomure a. ;..1j ,paramètres effectifs ne dépasse pas la valeur 9.
1:vsr wçrc 14 uurilIllanqe
et On
- j_r.
eval
i...
.
affichage des arguments dans l,ordre inverse
. de leur apparition lors de I'apoel on utilisera la commanae elrài en construisant une commande echo avec les paramètres inversés
#sh19: # # # #attention : ne fonctionne que partiellement à cause du nombre de paramètres formels récjuits à g #
if test $# -eq 0 then echo pas d\arguments else
echo -e "liste des arguments :', tr================,, gChO echo -e "\t $@"
-g
#construction de la commande echo coràPt=$g cmâe="echo -e \u\t " while test gcompt -gt 0 do
cmde="$cmde\ggcompt " compt='expr $compt - 1.
done cmde="$cmde \"" #fin de la construction
echo -e "liste des atguments dans l,ordre inverse :,, gChO _e r'===:==============:rtrtl======= evali$cmde
-
:
t
.. :.
:. '-. .: .'. t: .: ;: .. i '-" r...
.. -1. ':. .. r:1, :: :: l-11 ,-.
.._ . -..::::-_-
:' l-
--
--
:'
-
-
-
-
2 : Commandes système et prograrnmation Shell
E-rercices corripÉo
2: Conmandes
Shell
Exercices
RECHERCHE DE FICHIERS PAR FIND
rcice : ire un script shell permettant de facilitef I'utilisation de la commande l. L'objectif est de présenter un menu à I'utilisateur pour choisir quel ,e de recherche il voudra réaliser à partir d'un répertoire donnée. .emple : affichage de la liste des fichiers ordinaires, affichage de la liste s fichiers appartenant à un utilisateur donné, etc.
-script findl qui affïche une liste de fichiers I I
selon les besoins de l'utilisateur exprimés par un choix dans un menu
menuQ t echo -e':\t\t 0) quitter" echo -e "\t\t 1) sous répertoires de $dir" echo -e "\t\t 2) liste des fichiers ordinaires de $dir" echo -e "\t\t 3) liste des fichiers spéciaux de $dir" echo -e "\t\t 4) fichiers de $dir ayant une taille donnée" echo -e "\t\t 5) fichiers appartenant à un utilisateur donné" echo -e "\t\t 6) frchiers récemment mis à jour" echo -e "\t\t 7) fichiers récemment accédés" echo -e "\t\t 8) fichiers récemment créés' echo -e "\t\t 9) fichiers ayant des droits d'accès particuliers" )
rvhile true do gChO - g n\n==========:==========================r'
trap 'clear; exil' 2 3 egho -e "Répertoire à traiter : \c"; read dir if test 'l$dir' = r!'rr then dii-'pwd'. -- -elif test-d $dir
.
then:
t>z
echo -e ">>>>>>REPERTOIRE INCONNU <<<<<\n" exit 1
fi
menu ecbo -e "\n\t\tChoisir parmi : \c"; read choix case $choix in 0) exit;; r) find gdir -type d -print;; 2) find gdir \( .type f -o -rype I \) -print;; 3) frnd $dir \( -type c -o -type b -o rype p -o -rype s\) 4) echo -e "\ttaille min en octets : \c',; read min
min='expr gmin / 512' echo -e "\ttaille max en octets : \c,'; read max max= expr $max | 512'; max='expr $max + l' find $dir \( -size +$min -a -size -gmax \) -prinr
5) echo -e "\tnom de I'utilisateur: \c',; read nom
find gdir -user gnom -print
tt
6) echo -e "\tnombre de jours : \c"; read nbjour
find gdir -mtime -$nbjour -print
t)
7) echo -e "\tnombre de jours : \c"; rea{, nbjour
find gdir -atime -gnbjour -print ,,
8) echo -e "\tnombre de jours : \c"; read nbjour
find gdtime -$nbjour -print
9) echo -e "\tpermission d'accès : \c"; read droit
find gdir -perm -gdroit -print *) echo -e "\n>i>> ERREIJR atânS lâ
sâisie ! <<<<\n"
lr
"
,,
:, .1, ,;,. , 193--.;-.,+ '::., -. ':,' . -::
-_ r: --r_ :- r
' '-_
--.
: . ji:ji. . . -: . j: : , .
Exercice : shell qui va traquer la liste des fichiers de taille nulle et ffiG1"ript c"ux dont le uit suto est mis en place. Le script attend un paramètre en la spécification du chemin d'un répertoire à entrée qui doit corresponclre.à purti. aiqu.f la recherche va être opérée. Si ce paramètre est absent, il s'ag.t du réPertoire courant.
#script find2 traquant les fichiers de taille nulle #
et de SUID'BiI mis en Place
'
Publicité
if test $# 'gt 1 then
echo erreur : troP de Paramètres echo usage : $0 lPath] exit 1
fi
echo ${1:-'pwd'} 1>/dev/null D/dev/null echo $1
echo "liste des fichiers de taille nulle" g 6 | 6
= ====--==============tr
===
t t
nbre='find $1 'size 0 lwc 'l' find $1 -size 0 echo -e "\n))))))>>
TOTAL = $nbre \n"
echo "liste des fichiers avec SUID'BiI=1" g çf g tt ==== nbre='find g1 -perm +4100 | wc'l' find $1 -perm +4100
======================
echo -er1\n))>)))>>> TOTAL = $nbre \n"-
.
t, arborescence de racine le nom d'un répertoire et appartenant à un groupe ''d'utilisateurs donné, et qui vous propose au travers d'un menu soiide les afficher, deiles détruire ou de les archiver.
t
#script lind3 qui cherche tous les fichiers appartenant à un Tî JIr
groupe donné et qui exécute une commande parmi une liste donnée dans un menu
tt======================
function menuordre Q I( gglg echo " echo " , echo " i!'ècho "
A)rchiver D)étruire L)ister Q)uitter
t'
echo -n " )
votre choix : "
clear echo -n "nom du groupe : " l,read giroupe\ :. , t i if ! grep "^$groupe:" /etc/group l>/dev/null 2>/dev/null '.then echo "erreur : nom du groupe erroné !!!"
exit 1
II
-t::
,',echo .n "répertoire de recherche : "
...i
:.:.
i.i r:.;::j:.
'. :::''*-:+:
-i répertoire inexisant ou inaccesible"
i iit: ir::
menuordre read choix case $choix in [Aa]) echo -n "nom de I'archive : "; read archive
find $dossier -gïoup $groupe I cpio -ocvB > $archive
,t
tDd]) find $dossier -group $groupe 'exec rm 'f 0 \;
,t
[Ll]) find $dossier.group $groupe -print
tt
*) echo "erreur con'rmande inconnu" ; exit 3
esac
'i::lrf!..r.(fi:
:; -: .1
,r".il : .
&EçgEEçHq pre MormsFÀnGp
Exercice : rcrirg un script utirisant ra.-commande grep qui affiche res données complètes connues à propos d'un utilisateui. i" ,"ript sig'atera aJ pù, .l I'utilisateur en question posséde ou pas un mot de passe et si son uID et GID sont valides.
#script gp1 cherchant si un utilisateur est connu du système et si oui affiche ses données caractéristiques présentes -- dans le fichier /etc/passwd à savoircor, ùD,
-CfO,
4î
...
t
#attention : doit également indiquer si l'utilisateur a ou non # un mot de passe et renseigne sur la validité de Uù et # GID
'-:lti;i '"f,,ttclear
if test g# -ne 1 then
echo erreur: un paramètres est attendu
.. echo usage : $0 nom_utilisateur
exit I
.,,r
-,f i
.;r;.gggp=$l ,!i,1sg='gr€p "^$user:', /etc/passwd., ,, if ! test -z $res
'
:'i
.a:-? i'
then
, 't; ,r
IFS=: set-$res echo "infos de $user: " echo.l' if test then
- z$2
UID=$3, GID=$a,. HOME=$6,j,SHELL=$ 2,,
j
1
echo " !!!!ATIENTION: pas de mot de pâsse,,
196
t9't
I ll ll j'l tl I'ix-r
f!:1 it ! l!, I
case $3 in
*[!0-9]*) echc " !!!!IATTENTION: UID non valid.e"
esac case $4 in
*[!0-9]*) echo " !!!!!ATTENTION: GID non valide" ;; esac
else
echo "utilisateur Snom : inconnu"
Exercice : Ecrire un script utilisant la commande grep qui affiche les infomrarions relatives à tous les utilisateurs connus d'un groupe identifié par leur num éro.
#script grep2 affiche les informations concernant tous les utilisateurs d'un même groupe #
if test $# -eq 0 then echo erreur: paramètres attendus echo usage: $0 goupeld... exit 1
fi
for grp do
gç|tg r'======--=== case ggrp in
tfaitgmgnt
de $gfp ==============r'
*[!0-9]*) echo-$grp n\lest pas un nombre, ;;
r*)-ligùe='grêp
I'l [^:]*:[^:]*:[^:]*:$gtp:" /etc/passwd'
.1,'l:
Shell
Exerclccs
ech o$ lig ne Itr" ""1 n"
echo pas dYentrée pour le groupe $grp
else
- TT
I
'ti.i:
, a. i., r.: ,: e SaC i ,.'donê ril.,iï,
:
, ii-.,Exerclce *:l,iEr.ir. un script utilisant Ia commande grep qui prend comme paramètrcs une rrste.de noms de groupes et qui affiche la liste de ses membres et les
l, informations qui les concernent.
#script grepS qui pend la liste des utilisateurs cl'un sr.ouDe
,:;1;,# ,#
dont le nom est un paramètre donnée*et qui affiche leurs informations respectives
r, t' ,, ::if test $# -eq 0 :i.t hen i :
fil'
for g.p
i
':,lill1
echo erreur : paramètres attendus echo usage : g0 nom_groupe... exit 1 të i
ll
ggfig =--====== membre='grep "^ggrp:" /etclgroup lcut _f4 _d:.
ll2ilgment de $grp ==---=======
,"$iljl ''::i;ll' :,11'r if test -z "$membre" .'\il ri .r,:iii ,.then ,j.:U.,,r, . ,ti l ;i!
..: i . ,: thbn - $. .' elde .:-..-: .. -....
i .:. _ - !_..
_-L!_. -
..
echo liste des membres réduite à if grep "^$grp:" /etc/passwd
priori à ggrp
':J
else
echo $grp non utilisateur de ce système
Fr
echo liste des menbres du groupe $grp : $membre IFS=, set $membre while test -n "$1" do
grep "^$1" /etc/Passwd shift
done
fi done
2: Commandes
i' -: 'irr/ l' t : '-1
-
-i
'' . Exercices
LE TRANSFORMATEUR DE TEXTE AWK
.:f system("clear") ii print " ,;i. print "=No= =======contenu de Ia ligne==== ti, )
contenu du frchier : ", ARGVII]
de sélection particulière pour les actions qui suivent
F:#et qui concernent chaque ligne du fichier passé en paramètre 1i{
j
i t I ! t î I I l
! It
r;.rx ii, l'l l 4!
ll
\
lri
200
Fxercice:
:
i:ii Ecrire un script awk qui utilise les variables prédéfinieS pour afficher des -;.champs particuliers du fichier /etc/passwd. 1t ,;,: ,1#scrjpt.f2.awk qui renseigne à prrlpos 'ii# â: ?r BEGIN { '#F$='tttr #field separator"
des champs UID et GID du fichier /etc/passwd
print "\t le : ",.strftiàefl%D) iti"i ,,
"'
t'=====i56ut='-= ==========================r'
#rien { irint "username = " , $1," \t UID = ",$3, " \t GID = "'' $4 )
i
END { pf inf "==-========----===================f1n====tt l
Exercice : Ë..ir.in âu fichier /etc/passrvdet qui affiche le total des erreurs trouvées'
,"ript awk qui renseigne sur la validité des champs UID et GID
#script f3.awk qui renseigne à prop-os- de la validité #
des champs UID .t CtO du fichier /etc/passwd
BEGIN T FS=":" #field separator" compteur=0 ;;l;;';= )
valiàité de UID et GID dans le fichier /etc/passwd"
#les champs no 3 et 4 de chaque ligne du fichier /etc/pasrvrvd #doivent ne contenir que des chiffres sinon on incrémente le d" ,,o-u.e a urreur et on affîche à chaque fois un #;;;;;;;; #message approPrié
END { print "\n\t\t\t
I t
'.1
$$$$ TOTAL = ", compteur
. t Exercice : Ecrire un script awk qui calcule itérativenrent les factorielles cle l6 prenriers entiers et qui affichera leur résultat.
#script f4,arvk affichant les 16 premières valeurs de la factorielle (je ne sais si on perrt # aller plus loin !l) #
BEGIN
{
FactN_1=1 print "n \t factorielle(n)" print "0", "\t\t", FactN_1 for (i=1; i<-tS; i++; 1
FactN= i * FactN_l print i, "\t\t". FactN FactN_1= FactN
I
I I
#comme ctp n'est que du calcul (!) il n'l'a pas lieu de donner #une expr',ession pour la selection courante relative à une iigne #d'un fichier à traiter (n'est ce pas ???) et il en de même pour #une partie à introduire par END. #Iout cela montre qu'en fait awk esl un langage assez expressif #et qu'on peut imaginer I'utiliser autrelrent que pour traiter #des fichiers
, j.lil
?cûie 2 : Conarcndes $'s\ène et progrannation Shell
E-rercices corri-és-
',
Erercice: awk utilisant la stntcture de données tableau pour afficlrer ffil"ript le contenu d'un fichier ligne par ligne dans I'ordre inverse de leur apparitipn initiale.
#script f5.awk utilisant des tableaux #
affiche le contenu du fichier dans I'orclre inverse
BEGIN { print "\t\taffichage print'\f, l
inverse du contenu de : ",ARGV[l] \[======AVANT:-==================="
lÈrien {
l
Print "t ",$0 lignes[NR]=$0
END { print o\g\l===-===-APRES========= ==============" for(i:NR;i>0; i-') { print "< ",lignes[i] ] print -\1\t======================= l
=============="
Exercice: awk qui réalise les même calculs que la commande ivc Fit=-*.-r"ript (comprage du nombré <te caractères, mots et lignes d'un fichier) en ùtitisantles fonctions length, split, et en évitant de recourir aux variables prédéfinies NF et NR.
f6.awk gui compte le nombrè de caractères' mots et du-nÏô[ier doniié en paramètre ' "'-
#qcliltt ligne d'un # #attention: on'n'utilisera pas les variables précléfinies NF et $iR *
,;,. NF = nb de mots par ligne clu fichier (Numbel of Fielcls)
'1-1
NR = nb de lignes du fichier (Number of Row)
{
BEGIN print "$rvc " ARGV[1] nbli9=6 nbnrot=0 nbcar=0 l
. i:i :rl
{ nblig=nblio + 1 nbmot=nbmot + split($O, t, " ") nbcar=nbcar + length(90) + I l
END i prr