You are on page 1of 9

Objectifs du cours daujourdhui

apprendre crire des programmes en shell Unix : variables structures de contrle expressions logiques fonctions

Programmation oriente systme : C, Unix shell, Perl P ROGRAMMATION S HELL


Jean-Cedric Chappelier Laboratoire dIntelligence Articielle Faculte I&C

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Shell 1/34

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation S

Shell scripting
On peut crire des programmes en shell : succession de commandes
Mais attention aux diffrents dialectes : sh, csh, ksh, tcsh, zsh, ... Dans ce cours, nous allons voir la base : sh

Quest-ce quun programme shell ?


Cest un chier texte contenant une suite de commandes Unix excutable (chmod +x ...) On appelle de tels programmes des scripts Un script peut lui-mme devenir une commande, pour peu que le rpertoire o il se trouve soit contenu dans le PATH

Les programmes Shell (ou scripts ) sont utiles pour crire trs rapidement des petits programmes (systme essentiellement) factoriser des tches rptitives traiter beaucoup de chiers/rpertoires connecter plusieurs programmes (ltres et Glue Code ) faire des installations plus largement : conguration/maintenance du systme

le script soit auto-sufsant, cest--dire contiennent la descrip de son interprteur. Reprenons ces 2 aspects.

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Shell 3/34

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation S

le PATH Interprteur par dfaut


On a vu que la plupart des commandes Unix sont en fait des petits programmes extrieurs au shell lui-mme. Ces programmes sont cachs dans diffrents endroits du systme.  Comment linterprteur de commandes fait-il pour les trouver ? Il possde pour cela une variable denvironnement, cest--dire une variable faisant partie du shell, dont la porte est le processus shell lui-mme et ses ls, et qui dcrit les endroits possibles o chercher les commandes excuter. Cette variable sappelle PATH
echo $PATH /bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin

Pour donner un chier excuter un shell, il suft de le passer en argument linterprteur. Exemple :
sh macommande

...mais ce nest pas trs pratique !

On peut, dans des chiers programmes de langages interprts (to les shells, mais aussi perl, sed, awk, python, tcl, ...), donner au she appelant lindication de linterprteur lancer pour excuter le chi courant Cela se fait en indiquant le nom de linterprteur sur la premire ligne du chier aprs les deux caractres #! Exemples : #!/bin/sh #!/usr/local/bin/perl #!/bin/awk
c EPFL 20032007 Jean-Cedric Chappelier

Il est sage, dans un script sensible (i.e. important pour la scurit du systme), de limiter le PATH au minimum (e.g. /bin) en rednissant cette variable au dbut du script
c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Shell 5/34

` Programmation Orientee Systeme Programmation S

Excution interne
Au lieu de lexcution externe prsente prcdemment (nouveau processus), il est galement possible dexcuter le chier en interne. Lexcution interne ne cre pas de nouveau processus mais excute les commande au sein mme du processus shell courant. Dutilisation plus rare, elle permet surtout de congurer le shell courant (variables denvironnement, alias, ...) Pour excuter un script en interne dans un shell, il faut utiliser la commande source (en tcsh) ou . (en sh) : source macommande (tcsh) . macommande (sh)

Conguration

Il existe justement un certain nombre de chiers usuels de congu qui sont automatiquement excuts de faon interne lors du dmarrage dun shell.

Ces chiers dpendent du shell utilis (voire du systme) mais pou tcsh : $HOME/.login est excut dans le shell de login $HOME/.tcshrc est excut au dbut de chaque shell tcsh $HOME/.logout est excut avant de quitter le systme

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Shell 7/34

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation S

Listes dinstructions Bases de lcriture de script (sh)


Commencez par lindication de linterprteur #!/bin/sh Une instruction par ligne, ou plusieurs instructions par ligne spares par des ; Commentaires : depuis # jusqu la n de la ligne Exemple : ls > ../content # ceci est un commentaire Le script se termine soit la n du chier soit quand lexcution rencontre linstruction exit Une liste dinstructions est une squence dune ou plusieurs commandes spares par ;, && ou || et termine par ;, & ou un retour la ligne.

Si une commande se termine par &, la commande est excute en tche de fond dans un processus shell ls. Le shell pre nattend p la n de la commande.

Les commandes spares par des ; sont excutes une aprs lau le shell attendant la n de lexcution de chacune.
&& reprsente le ET logique entre (statut de) commandes. commande1 && commande2 : commande2 nest excute que si commande1 se termine et son statut est 0 || reprsente le OU logique entre (statut de) commandes. commande1 || commande2 : commande2 nest excute que si commande1 se termine et son statut est diffrent de 0 (i.e. normalement un code derreur)

Le statut dun ET ou dun OU est le statut de la dernire command excute.


c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Shell 9/34

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Sh

Variables
En shell de base (Bourne shell, sh), les variables ne sont pas types (sont toutes des chanes de caractres) se dsignent par un nom constitu exclusivement de caractres alphanumriques ou _ et ne commenant pas par un chiffre affectation :
nom=valeur

Variables portes
Il existe 2 sortes de variables, en fonction de leur porte : variables locales : porte limite au processus courant Convention : noms en minuscules variables denvironnement : porte comprenant le processus courant et tous les processus ls (et, par rcurrence, autres descendants) Convention : noms tout en MAJUSCULES Exemple : PATH Pour dclarer une variable comme variable denvironnement, utiliser export Exemple :
MYOWNPGM_HOME=/usr/share/myownpgm export MYOWNPGM_HOME

Attention ! PAS DESPACE autour du signe = ! Exemples : suffixe=.tex noms="Pierre Paul Jacques Jean" Utilisation de la valeur : Exemples : echo $PATH ls -l "$fichier"
c EPFL 20032007 Jean-Cedric Chappelier

$nom

Note : il faut souvent protger cette valeur par des guillemets an dviter une mauvaise interprtation des blancs quelle pourrait ventuellement contenir.

Notez quil y a pas de $


` Programmation Orientee Systeme Programmation Shell 11/34
c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Sh

Variables denvironnement usuelles


Pour connatre toutes les variables denvironnement : env variable
PATH HOME SHELL USER DISPLAY HOSTNAME HOSTTYPE OSTYPE

Variables particulires
Dans les scripts, il existe un certain nombre de variables dj prdnies (en plus des variables denvironnement hrites du processus pre) les arguments (rcuprs de la ligne de commande) : $0 : le nom du script courant $1 : la valeur du premier argument $2 etc... : autres arguments dans lordre

contenu lieux de recherche des commandes chemin absolu du rpertoire principal de lutilisateur linterprteur shell excut le nom dutilisateur (du shell courant) adresse de lcran nom de la machine type de CPU quel systme dexploitation

Exemple de valeur
/bin:/usr/bin:.... /home/chaps /bin/tcsh chaps :0.0 insunrays3 x86_64 linux-gnu

(la commande shift permet de les dcaler : $3 $2 $1, voir transparent suivant)

$# : le nombre darguments $? : la valeur de retour de la dernire commande excute Exemple : resultat=ls $fichier if [ $? -ne 0 ]; then ... $$ : PID du process courant
c EPFL 20032007 Jean-Cedric Chappelier

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Shell 13/34

` Programmation Orientee Systeme Programmation Sh

Variables particulires (suite) Gestion des arguments


$* : concatnation de tous les arguments ($1, $2, ...), mais mauvaise gestion des blancs !  ne pas utiliser. "$@" : tous les arguments, protgs en cas de blancs Il y a donc deux bonnes faons de faire une boucle sur les arguments : soit une boucle tant que $# est positif et utilisant shift :
while [ $# -ne 0 ]; do arg=$1 shift ... # utilisation de $arg done

Gestion des arguments : Exemple


Le programme suivant (stock dans le chier args.sh) :
#!/bin/sh echo "\$#=\"$#\"" echo "\$1=\"$1\"" echo "\$*=\"$*\"" echo "boucle 1 :" echo "boucle 2 :" echo "boucle 3 :" echo "boucle 4 :" ; ; ; ; ; ; for x for x for x while echo "\$0=\"$0\"" echo "\$2=\"$2\"" in $* ; in $@ ; in "$@" ; [ $# -ne 0 ]; do do do do echo echo echo echo

"\"$x\""; "\"$x\""; "\"$x\""; "\"$1\""; shift

donnera par exemple pour lappel suivant :


tcsh$>./args.sh a "Betty Boop" CC $#="3" $0="./args.sh" $1="a" $2="Betty Boop" $*="a Betty Boop CC" boucle 1 : [FAUX] "a" "Betty" "Boop" "CC"
c EPFL 20032007 Jean-Cedric Chappelier

soit dans une itration sur "$@" (attention bien mettre les guillements !) :
for arg in "$@"; do ... # utilisation de $arg done
c EPFL 20032007 Jean-Cedric Chappelier

boucle 2 : [FAUX] "a" "Betty" "Boop" "CC"

boucle 3 : [OK] "a" "Betty Boop" "CC"

boucle 4 : [OK] "a" "Betty Boop" "CC"

` Programmation Orientee Systeme Programmation Shell 15/34

` Programmation Orientee Systeme Programmation Sh

here-document
Il est possible de fournir directement du texte une commande (en redirigeant son stdin) : commande << EOF ..du texte.. EOF Un intrt de cette possibilit est de passer dans le texte la valeur de certaines variables. Exemple :
cat > /tmp/config.txt << EOF user : $USER install dir : $directory verbose option : $verbose color : $color EOF

Structures de contrle
branchement conditionnel if list; then list; [ elif list; then list; ] [ else list; ] fi Exemple : resultat=ls $fichier if [ $? -ne 0 ]; then echo "je ne peux pas lister $fichier" else echo "rsultat ($fichier) :" e echo $resultat fi boucles while list; do list; done Exemple : while [ $continuer -ne 0 ]; do ... done

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Shell 17/34

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Sh

Structures de contrle (2)


choix multiples case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac Exemple : read reponse case $reponse in oui|Oui|OUI) echo "OK jefface" rm $choix continuer=0 ;; [Nn][Oo][Nn]) echo "Bon, tant pis !" continuer=0 ;; *) echo "pas compris" ;; esac

Structures de contrle (3)


itration for name [ in word ] ; do list ; done Exemple : for file in *.txt; do if [ -r "$file" ]; then echo " ---- $file ----" cat "$file" fi done

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Shell 19/34

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Sh

Principaux tests Expressions logiques


La commande la plus utilise pour les arguments des branchements conditionnels et les boucles conditionnelles est la commande test qui renvoie la valeur boolenne correspondant divers tests portant sur ses arguments : type de chier : -[bcdfhpt] droit daccs : -[gukrwx] caractristique de chier : -s chanes de caractres : -z -n = != tests numriques : -eq -ne -lt -le -gt -ge connecteurs : non : !, et : -a, ou : -o Exemple :
test -r "$file" -n chaine -z chaine chaine1 = chaine2 chaine1 != chaine2 int1 -eq int2 int1 -ne int2 int1 -ge int2 int1 -gt int2 int1 -le int2 int1 -lt int2 -d name -f name -h name -r name -w name -x name

test args peut aussi scrire [ args ] (Attention aux espaces !)

la chane nest pas vide la chane est vide les deux chanes sont gales les deux chanes sont diffrentes galit diffrents > < name est un rpertoire name est un chier name est un lien symbolique name peut tre lu name peut tre crit name peut tre excut

Exemple :
c EPFL 20032007 Jean-Cedric Chappelier

[ -r "$file" -a ! -d "$file" ]
` Programmation Orientee Systeme Programmation Shell 21/34
c EPFL 20032007 Jean-Cedric Chappelier

Pour plus de dtails : man test

` Programmation Orientee Systeme Programmation Sh

Exemple
#!/bin/sh fichier=$1 echo "Searching for file $fichier in subdirectories." found= for dir in *; do if [ -d "$dir" ]; then if [ -f "$dir/$fichier" ]; then echo "$fichier found in $dir" found="ok" fi fi done if [ ! "$found" ]; then echo "File $fichier not found in subdirectories." fi #!/bin/sh

Autre criture

fichier=$1 echo "Searching for file $fichier in subdirectorie for dir in * do if test -d "$dir" then if test -f "$dir/$fichier" then echo "$fichier found in $dir"; found=1 fi fi done if test -z "$found" then echo "File $fichier not found in subdirectorie fi

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Shell 23/34

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Sh

Fonctions (Exemple) Fonctions


#!/bin/sh

Il est possible de crer des fonctions dans un script. La syntaxe gnrale est la suivante : name () { list } Dans une fonction, les arguments sappellent galement : $1, $2, ... Attention ! ne pas confondre avec les arguments reus de la ligne de commande !

lookfor () { if [ -d "$1" ]; then if [ -f "$1/$2" ]; then echo $1 return 0 fi fi return 1 } echo "Searching for file $1 in subdirectories." for dir in *; do res=lookfor "$dir" "$1" if [ $? -eq 0 ]; then echo "$1 found in $res" else echo "File $1 not in $res." fi done

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Shell 25/34

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Sh

Exemple avanc (1/3) gestion des signaux


Rappel : les processus peuvent recevoir des signaux, en particulier par la commande kill (cf semaine passe).
(vous tudierez les signaux plus en dtails dans le cours de systmes dexploitation )
#!/bin/sh # # ps2pdf-slides # (c) Jean-Cedric Chappelier 05/01 # prog=/bin/basename $0 temp=/tmp/$prog-$$.ps

La commande trap permet de grer dans le script les signaux quil reoit :
trap commande signaux

# where to put the new gs_statd.ps. This has to be user writab gs_statddir=/tmp gs_statd=$gs_statddir/gs_statd.ps trap /bin/rm -f $temp $gs_statd >/dev/null 2>&1; exit 0 0 1

Exemple classique : supprimer les chiers temporaires en cas de terminaison du processus


trap /bin/rm -f $temp >/dev/null 2>&1; exit 0 0 1 2 3 15

usage () { echo "usage: $prog [-h|-?] input.ps [output.pdf]" } error () { echo $* 1>&2 usage exit 1 }

trap -l pour avoir la liste (et numros) de signaux


(cest un L minuscule, pas un 1)

Note : le signal 0 reprsente par convention la terminaison normale du processus (i.e. EXIT).
c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Shell 27/34

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Sh

Exemple avanc (2/3)


help () { usage echo " -h or -? : Print this message and stops." echo "input.ps : The file to be converted" echo "output.pdf : The name where to put the conversion. If not specified" echo " the output will be .pdf extention of input filename" exit 0 } while [ $# -ge 1 ]; do case "$1" in -h|-\?) help;; input=$1;; *.ps) *.pdf) output=$1;; esac shift done if [ -z "$input" ]; then error "No input.ps file!" fi output=${output:-basename "$input" .ps.pdf}

Exemple avanc (3/3)


# Creates gs_statd.ps file cat > $gs_statd <<EOF ici du texte utile a mettre dans le fichier gs_statd.ps EOF if [ $? -ne 0 ]; then error "Cannot create $gs_statd file" fi

sed -e s/%%BoundingBox: 0 0 596 842/%%BoundingBox: 0 0 842 5 -e / *@landscape *$/ d -e /%%DocumentPaperSizes: A4 *$/ d -e /%%Orientation: Landscape *$/ d -e /%%PaperSize: A4 *$/ d "$input" > $temp if [ $? -ne 0 ]; then error "Cannot read $input file" fi ps2pdf -I$gs_statddir -sPAPERSIZE=a4r $temp "$output" if [ $? -ne 0 ]; then error "Cannot execute ps2pdf!" fi

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Shell 29/34

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Sh

Shell Programmation (1/2)


variables denvironnement : HOME, PATH, SHELL, DISPLAY, ... env : pour la liste (et le contenu) PATH : indication des endroits o chercher les commandes programme shell = script = succession de commandes langage interprt non typ Commencer par lindication de linterprteur : #!/bin/sh Commentaires : depuis # jusqu la n de la ligne Une instruction par ligne, ou plusieurs instructions par ligne spares par des ; variables : affectation : nom=valeur , utilisation : $nom variables spciales : $$ : PID, $0, $1, ... : arguments, $# : nombre darguments, $? : statut dernire commande
c EPFL 20032007 Jean-Cedric Chappelier

Shell Programmation (2/2)

branchements conditionnels if list; then list; [ elif list; then list; ] [ else list; ] fi boucles while list; do list; done choix multiples case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac itrations for name [ in word ] ; do list ; done tests logiques : test args ou [ args ] man test pour les dtails

` Programmation Orientee Systeme Programmation Shell 31/34

c EPFL 20032007 Jean-Cedric Chappelier

fonctions : name () { list } texte inline : commande << EOF ..du texte.. EOF ` Programmation Orientee Systeme Programmation Sh

Ce que jai appris aujourdhui


Comment crire des shell-scripts : variables structures de contrle test logiques (attributs de chiers) fonctions

La suite
semaine prochaine : dbut de la programmation en C langage gest. mmoire Fichiers Processus/Threads Rseaux C + + + (cours SE) / Perl N.A. + / / Shell + N.A. + + N.A. Java + N.A. +

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Shell 33/34

c EPFL 20032007 Jean-Cedric Chappelier

` Programmation Orientee Systeme Programmation Sh

You might also like