Professional Documents
Culture Documents
apprendre crire des programmes en shell Unix : variables structures de contrle expressions logiques fonctions
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
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.
Pour donner un chier excuter un shell, il suft de le passer en argument linterprteur. Exemple :
sh macommande
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
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
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)
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.
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
soit dans une itration sur "$@" (attention bien mettre les guillements !) :
for arg in "$@"; do ... # utilisation de $arg done
c EPFL 20032007 Jean-Cedric Chappelier
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
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
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
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
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
usage () { echo "usage: $prog [-h|-?] input.ps [output.pdf]" } error () { echo $* 1>&2 usage exit 1 }
Note : le signal 0 reprsente par convention la terminaison normale du processus (i.e. EXIT).
c EPFL 20032007 Jean-Cedric Chappelier
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
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
fonctions : name () { list } texte inline : commande << EOF ..du texte.. EOF ` Programmation Orientee Systeme Programmation Sh
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. +