Sie sind auf Seite 1von 10

Langage de commandes Shell

Gnralits :
Le Shell est la fois un langage de commandes (shell script) et l'interprteur de ce langage. Il assure l'interface externe entre les utilisateurs et le systme, mais ne fait pas partie du noyau. Principaux langages de commandes sont disponibles sur les systmes UNIX et GNU/Linux : csh (C-Shell), ksh (Korne-Shell), bash (Bourne Again-Shell). L'interprteur du shell a la possibilit, soit d'excuter lui mme la commande demande par l'utilisateur (commande interne), soit de lancer l'excution de programmes existant par ailleurs pour ce faire (commandes externes). A chacune des commandes externes correspond un fichier excutable ayant comme nom le nom de la commande. Ce fichier se trouve souvent dans le rpertoires /bin. L'excution d'une commande externe entrane la cration d'un nouveau processus excutant le programme correspondant la commande. Une commande externe peut tre appele partir de n'importe lequel des langages de commandes disponibles, mais aussi partir d'un programme utilisateur. Chacun des langages de commandes dispose de ses propres commandes qui sont les commandes internes.

Mcanisme d'excution d'une commande :


Vous avez dj vu qu'UNIX propose une vaste gamme de commandes et qu'il est possible d'en dfinir de nouvelles. Cela diffrencie radicalement de beaucoup d'autres os, Operating System (sytme d'exploitation). Une commande sous un systme de type UNIX (GNU/Linux et *BSD) est un simple fichier. La commande ls par exemple existe sous la forme d'un fichier binaire situe dans le rpertoire /bin. Par consquent au lieu de taper ls vous pourriez entrer /bin/ls. Les commandes entres par un utilisateur, aussi bien celles entres au clavier que celles lances par un programme (script) permettant d'excuter des travaux ou tches de fond (job batch), sont toujours reues par un interprteur (shell). Le shell est vu par les systmes comme un processus. Une commande reue par le shell peut tre excute par le shell ; sinon, elle est excute dans un autre processus qui est cr par le shell. Le nom de la commande Bourne Again Shell est bash ; c'est un interprteur de commandes avec une syntaxe similaire au langage C, un mcanisme d'historique (history) et une facilit de contrle de travaux (job). Le code de retour d'une commande est aussi un mcanisme fourni par le shell (quel qu'il soit) qui signale l'utilisateur si l'excution de cette commande s'est bien droule ou bien s'il y a eu un problme quelconque. Le code de retour est un petit entier positif ou nul, toujours compris entre 0 et 255. Par convention, un code de retour gal 0 sans erreur (attention, c'est l'inverse du langage C !) signifie que la commande s'est excute correctement. Un code diffrent de 0 signifie soit une erreur d'excution, soit une erreur syntaxique. Une variable systme spciale $? contient toujours la valeur de retour de la prcdente commande (on peut afficher cette valeur avec la commande echo) : le paramtre spcial ? du shell ( ne pas confondre avec le caractre gnrique ? du shell) contient le code de retour de la dernire commande excute de manire squentielle ; on emploie galement l'expression excution synchrone. L'excution squentielle signifie que le shell n'excute une commande que lorsque la prcdente s'est termine. C'est bien sr le mode d'excution par dfaut d'une commande :

ex : pwd /home/totoaffiche le rpertoire courant de travail echo$?vrification du code de retour 0affichage du code de retour 0 : la commande s'est excute correctement lslvi ls:vi:Aucunfichierourpertoiredecetypeaffiche le message d'erreur echo$? 1affichage du code de retour : erreur d'excution ! Dans l'exemple prcdent, la commande ls ne trouve pas le fichier correspondant l'diteur de texte vi dans le rpertoire courant (ce qui est tout fait normal !) et positionne un code de retour 1. En bash, il est possible d'obtenir la ngation d'un code de retour d'une commande en plaant ! devant celle-ci. Cela signifie que si le code de retour de la commande est gal 0, alors le code de retour de ! est gal 1 : ex : !lsfichierle code de retour de lsfichier est gal 0 fichieraffiche le fichier s'il existe echo$? 1le code de retour est gal 1 car ! est plac devant la commandels Le code de retour d'une suite de commandes est le code de retour de la dernire commande excute. Le code de retour de la suite de commandes cmd1;cmd2;cmd3 est le code de retour de la commande cmd3 : ex : pwd;lsvi;echobonjour /home/toto ls:vi:Aucunfichierourpertoiredecetype bonjour echo$? 0code de retour de echobonjour Il en est de mme pour le tube (pipeline) cmd1|cmd2|cmd3. Le code de retour sera celui de cmd3 : ex : cat/etc/passwd|grepdaemon daemon:x:2:2:daemon:/sbin:/sbin/nologin echo$? 0 code de retour de grepdaemon (*) Note : un problme qui se pose au dbutant lorsqu'il utilise le code de retour d'une commande, sous les systmes UNIX : c'est que chaque commande positionne sa manire les codes de retour diffrents de 0. Ainsi, un code de retour gal 1 positionn par la commande ls n'a pas la mme signification qu'un code de retour 1 positionn par la commande grep. Il n'existe qu'une seule solution ce problme : lire le manuel correspondant la commande.

Evaluation de commandes : bash est le shell le plus utilis avec GNU/Linux. Le shell permet de donner des instructions au systme en ligne de commande. Lorsque l'on tape une instruction, le premier mot est la commande elle-mme. Ensuite viennent les paramtres ventuels. Le shell va alors essayer de trouver quoi la commande correspond dans l'ordre suivant. Tout d'abord si la commande contient une spcification d'emplacement, le programme se trouvant dans ce rpertoire est excut s'il s'y trouve et si l'utilisateur a les droits adquats. Sinon une erreur est affiche. Ensuite bash regarde quels alias sont dfinis. Un alias est un moyen d'excuter une commande par un raccourci. Pour que par exemple le fait de taper mon_alias excute ma_commande, il faudra dclarer l'alias comme ceci : ex : aliasmon_alias='ma_commande' Les guillemets ne sont utiles que si la commande a des paramtres (c'est dire qu'elle contient des espaces). Le contenu de ma_commande sera valu selon le mme schma pour trouver le programme excuter : ex : mon_aliasparamtre1paramtre2 Tout se passe comme si ma_commande avait t tap la place de mon_alias. Il va donc aussi avoir les paramtres. Si aucun alias n'est trouv, ce sont alors les fonctions qui sont examines. Une fonction est un moyen de regrouper plusieurs commandes. Et de faire des traitements plus complexe qu'avec un alias. Une fonction (function) se dclare comme ceci : ex : functionma_fonction(){ma_commande1;ma_commande2;} Pour la dfinition de la fonction (function), on peut omettre le mot-cl fonction ou les parenthses, mais au moins un des deux doit tre prsent. Le point-virgule (;) permet de sparer les commandes et aussi de les terminer. A l'intrieur de la fonction (function), des variables positionnelles ($1, $2, ...) sont dfinies automatiquement par le shell. Elles correspondent aux paramtres passs la fonction : ex : functionmon_affichage{echo"SAIT:$1";} mon_affichageBonjourappel de la fonction SAIT:Bonjouraffichage du rsultat Dans le cas o aucune fonction correspondant n'existe, le shell consulte ses commandes intgres (shell builtin commands). Avec bash, on peut citer comme exemple de commandes intgres cd (pour changer le rpertoire courant) ou echo vu prcdemment. Enfin le shell parcourt les rpertoires contenus dans la variable d'environnement $PATH pour y chercher un programme du nom tap. Si celui-ci est trouv, il est excut, sinon une erreur est affiche : ex : echo$PATH /home/toto/bin:/usr/local/bin:/usr/bin:/bin

Si deux programmes avec le mme nom se situent dans /usr/local/bin et /bin, c'est le premier qui sera excut. En rsum voici l'ordre d'valuation si la commande est excute sans spcification de chemin : alias, fonction, commandes intgres, excutables dans un des rpertoires de $PATH. Si tout cela choue, un message d'erreur sera affich. La commande type permet de savoir quelle catgorie appartient une commande. Dans les deux premiers cas, on a la correspondance de l'alias ou de la fonction (function). Les commandes intgres sont indiques par un texte gnrique et pour le dernier cas, le chemin de l'excutable est affich. Lorsque l'on excute une commande, bashcre un sous-shell pour le lancer. C'est--dire que cela se passe comme si on avait lanc une nouvelle fois bash. Pour modifier ce comportement, on peut placer un point (.) en dbut de ligne. Cela provoquera alors l'excution dans le shell courant : ex : .ma_commandeexcute la commande (ne pas oublier l'espace entre le point et la commande) Historique des commandes : bash conserve les dernires commandes tapes afin de pouvoir facilement les retrouver. Elles sont sauvegardes en mmoire pour le shell courant si plusieurs sont lancs. Et lorsque celui-ci est quitt, elles sont crites dans le fichier .bash_history qui se trouve la racine du rpertoire personnel de l'utilisateur (~). Ce fichier est celui par dfaut, son nom peut tre chang par la variable d'environnement $HISTFILE. Le nombre de prcdentes commandes sauvegardes en mmoire est dfini par la variable $HISTSIZE (par dfaut 1000) et le nombre devant tre sauvegardes dans le fichier par la variable $HISTFILESIZE (galement 1000 par dfaut). Les commandes sont sauvegardes avant la substitution ventuelle faite (si des caractres *, ? ou []sont prsents). Pour parcourir l'historique, il suffit d'utiliser les touches flches ( gauche du pav numrique). La flche vers le haut permet de parcourir les commandes dans l'ordre inverse de leur excution et la flche vers le bas dans l'autre sens. Peuvent galement tre utilises respectivement les combinaisons [CtrlP] (previous) et [CtrlN] (next). Pour les habitus de l'diteur de texte Emacs, ce sont les combinaisons de touches de ce logiciel qui peuvent tre utilises pour diter les commandes entres. De mme que dans cet diteur, on peut rechercher parmi les commandes prcdentes. Pour cela il suffit de de maintenir les touches [CtrlR]. Apparat alors une invite permettant la recherche de la forme suivante : ex : (reverseisearch)`': Qui remplace alors l'invite de commande habituelle. La recherche se fait de manire incrmentale. C'est dire qu'au fur et mesure que l'on tape des caractres, la plus rcente ligne de l'historique trouve sera affiche. Pour interrompre la recherche, on peut appuyer simutanment [CtrlG] ou une des touches flches (gauche et droite permettant alors de l'diter). La touche [Enter] permet d'excuter la commande affiche.

Le Shell script (programmation Shell)


Les diverses commandes, que nous avons vu jusqu' prsent saisies sur une ligne de commande, peuvent aussi tre stockes dans un fichier. Aprs avoir dot le fichier de lignes regroupes de commandes shell, il faut les autorisations d'excution (x) la l'aide de la commande chmod, de cette manire le nom du fichier peut-tre utilis comme une commande normale : ex : vistatuscontiendra les lignes suivantes : #Dbutdefichier:uncommentaireestprcdparlecaractre# pwd#indiquelerpertoiredetravail lsl#listelesfichiers who#montrequiestconnect :wq appuyez [Esc] puis enregistrez (w) le fichier en quittant (q) l'diteur vi chmodu=rwx,go=xstatusdonne la permission d'excuter le script tous les utilisateurs Si vous excutez la commande status dans le shell vous constaterez que l'erreur 127 est leve : ex : statusexcution de la commande bash:status:commandnotfoundmessage d'erreur : la commande n'est pas trouve echo$?code de retour diffrent de 0:127 Cela signifie simplement que le shell cherche ce fichier au mauvais endroit dans l'arborescence. Il ne cherche pas obligatoirement dans le rpertoire courant. Il faut spcifier explicitement ce rpertoire source, c'est dire dire soit en spcifiant le chemin absolu plus le script excuter, soit en se plaant dans son rpertoire courant (dans ce cas on l'appel par ./) : ex : /home/toto/statusspcifie le chemin absolu du fichier a excuter ./statusappel de la commande depuis son rpertoire courant toto Le shell interprte les scripts l'excution commande aprs commande. Le shell commence par vrifier s'il s'agit d'une commande interne ou externe. Si c'est une commande externe, le shell cherchera des endroits bien prcis de l'arborescence, pour trouver le fichier de mme nom. S'il le trouve un second test test est effectu. Au cours de ce second test, le shell vrifie s'il s'agit d'un fichier binaire ou d'un script (*). Dans tous les cas un nouveau shell est lanc. Le shell charge le fichier binaire si la commande est un nom de programme. Dans le cas d'un script le nouveau shell interprtera les commandes les unes aprs les autres. Les scripts shell externes sont des fichiers de configuration, des programmes pouvant excuter des tches particulires : parefeu (firewall), sauvegarde (backup), redirection (forward) et services ou dmons (daemons) : ex : lsl/etc/init.drpertoire contenant les scripts shell permettant d'initialiser des services lancs par le processus init lsl/etc/profile.drpertoire spcial permettant de stocker des shell scripts appels par le fichier de configuration profile vi/etc/profilevisualise le fichier de configuration (*) Note : les quatre premiers caractres d'un fichier binaire contiennent un code d'identification spcial (une espce de nombre magique). Les shell scripts n'ont pas ce code d'identification.

Excution et structure conditionnelle (cration d'un script shell) : test, [ ], if et else


Une procdure (script shell) est une suite de commandes shell. Elle peut accepter des paramtres : ex : commandeparamtre1paramtre2...paramtren (nime paramtre). Le premier paramtre est rfrenc par $1, le second par $2, ..., le neuvime par $9 : ex : $1, $2, ..., $9sont des paramtres de commande La cration d'un script commence en gnral par la ligne #!/bin/bashdclarant le type de shell qui sera appel pour interprter les commandes. Dans ce cas nous utilisons le bash : ex : #!/bin/bash #Essaidescript:cescriptpermetdetesterlaprsencedes #paramtresdelacommande #Cettecommandeexterne(scriptshell)doitcomporterdeuxarguments PATH=$PATH:/home/toto/myscript; #Cheminderecherchedunomdela #commande exportPATH #Exportelavariableduchemin usage(){ #Nomdelaprocdure echo"usage:$1$2" #Affichelesparamtres } main(){ #Procdureprincipale if[$#=0];then #Testesinombredeparamtres=0 usage`basename$0`"fichier";#appeldelaprocdureusage exit1 #Coderetour1 fi #Findelaconditionif } main$* Excution conditionnelle : Si la commande test permet de vrifier la ralisation d'une condition en renvoyant un code de retour (valeur de retour). La commande test peut tre remplace par des crochets [] : ex : testrxyz&&Lefichierxyzestlisibleenchanement avec && echo$? [ rxyz]&&Lefichierxyzestlisibleidem En relation avec test mais cette fois pour piloter l'ordre d'excution des commandes dans un fichier de script shell, nous utilisons des structures de contle. Ces structures de contrle permettent de dcider de l'excution d'une commande en fonction de la ralisation d'une condition, c'est notamment le cas des structure de type if. L'instruction if permet de tester une suite de commandes, mais aussi une expression place entre [] afin d'excuter des instructions si une condition est vraie. L'lment important est la valeur de retour de la dernire commande de cette suite. S'il s'agit de 0 toutes les commandes places derrire le mot cl then sont excutes. Si la valeur de retour est diffrente de 0, ce sont les commandes places derrire le mot cl else qui seront excutes :

Condition simple :

suite de commandes ifsuite_commandesthen commandes fi ex : ifgrepPATH/etc/profile>/dev/null2>&1;then echoCheminabsolu(recherchePATHexcutiondecommande):$PATH fi

avec paramtres echo$1trouv fi

ex : ifgrep$1/etc/profile>/dev/null2>&1;then

expression/condition entre crochets if[expression_condition]then action fi ex : if[$#=0];then echoErreur:Appel:$0Critre>&2 fi ifgrep$1/etc/profile;then echo$1trouv fi action est une suite de commandes quelconques. L'indentation (4 espaces) n'est pas obligatoire mais trs fortement recommande pour la lisibilit du code. On peut aussi utiliser la forme complte : Condition avec alternative : suite de commandes ifsuite_commandesthen commandes else commandes fi ex : ifgrepPATH/etc/profile;then echoCheminabsolu(recherchePATHexcutiondecommande):$PATH else echoAucunchemin fi

paramtres ex : ifgrep$1/etc/profile;then echo$1trouv else echo$1nontrouv fi

avec expression/condition entre crochets if[expression_condition]then action else action fi ex : if[$#=0];then echo"Erreur:Appel:$0Critre:aucun:Nombre:$#">&2 exit1 else echo"Succs:Appel:$0Critre:$1:Nombre:$#" exit0 fi Condition multiple :

suite de commandes ifsuite_commandesthen commandes elifcommandethen commandes else commandes fi

avec expression/condition entre crochets ex : if[expression1_condition1];then action1 elif[expression2_condition2];then action2 else[expression3_condition3] action3 fi En vous inspirant du modle de la condition multipe ci-dessus simplifiez le script shell ci-dessous : #!/bin/bash if[$#=0] then echo"Erreur:Appel:$0Critre:aucun">&2 exit1 else ifgrep"$1"$2>/dev/null2>&1 then echo"$1trouvdans$2" else echo"$1nontrouv" fi exit0 fi

Oprateurs de comparaison : Le shell tant souvent utilis pour manipuler des fichiers, il offre plusieurs oprateurs permettant de vrifier diverses conditions sur ceux-ci : existence, dates, droits. D'autres oprateurs permettent de tester des valeurs, chanes ou numriques. Ci-dessous un aperu des principaux oprateurs : Oprateurs sur les fichiers : enom_fichier vrai si nom_fichier existe ex : [e/etc/shadow] dnom_fichiervrai si nom_fichier est un rpertoire ex : [d/tmp/trash] fnom_fichiervrai si nom_fichier est un fichier ordinaire ex : [f/tmp/glop] Lnom_fichiervrai si nom_fichier est un lien symbolique ex : [L/home] rnom_fichiervrai si nom_fichier est lisible (r) ex:[r/boot/vmlinuz] wnom_fichiervrai si nom_fichier est modifiable (w) ex : [w/var/log] xnom_fichiervrai si nom_fichier est excutable (x) ex : [x/sbin/halt] fichier1ntfichier2vrai si fichier1 plus rcent que fichier1 ex : [/tmp/foont/tmp/bar] fichier1ofichier2vrai si fichier1 plus ancien que fichier2 ex : [/tmp/fooot/tmp/bar] Oprateurs sur les chanes : zchainevrai si la chaineest vide ex : [z"$VAR"] nchainevrai si la chaine est non vide ex : [n"$VAR"] chaine1=chaine2vrai si les deux chanes sont gales ex : ["$VAR"="toto"] chaine1!=chaine2vrai si les deux chanes sont diffrentes ex : ["$VAR"!="titi"]

Oprateurs de comparaison numrique : num1eqnum2galit ex : [$nombreeq37] num1nenum2ingalit ex : [$nombrene37] num1ltnum2infrieur (<) ex : [$nombrelt37] num1lenum2infrieur ou gal (<=) ex : [$nombrele37] num1gtnum2suprieur (>) ex : [$nombregt37] num1genum2suprieur ou gal (>=) ex : [$nombrege37] Expressions arithmtiques : On peut facilement valuer des expressions arithmtiques avec bash. Pour cela, on utilise la notation $(()) qui sera remplace par le rsultat du calcul mathmatique. Voici les oprations pouvant tre utilises par ordre de priorit inverse (extrait de la page de manuel de bash) : +plus et moins unaire !~ngations logique et binaire */%multiplication, division, reste +addition, soustraction <<>>dcalage arithmtique gauche et droite <=>=<>comparaisons ==!=galit et diffrence &ET binaire, ^OU exclusif binaire, |OU binaire, &&ET logique, ||OU logique =*=/=%=+==<<=>>=&=^=|=assignations bash effectuera le remplacement par la valeur avant l'excution des commandes ventuelles. La commande suivante est une erreur : ex : $((variable=3+2)) bash:5:commandnotfoundla variable contiendra bien la valeur 5 la suite de cette action. Mais bash a remplac l'expression par sa valeur, donc tout se passe comme si on avait uniquement saisi 5 l'invite (qui se trouve tre un programme inconnu). Une autre notation est possible en mettant $[] autour de l'expression la place de $(()).

Das könnte Ihnen auch gefallen