Shell Programming Exercises

Shell Scripting, Programming, Unix Commands · lab

Voir tous les documents en systèmes d'exploitation et cloud

.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