Séance 5 : Automatisation et scripts§
Département Informatique (IUT Lyon 1)
Ce travail est sous licence Creative Commons Attribution-ShareAlike 3.0 France.
Département Informatique (IUT Lyon 1)
Ce travail est sous licence Creative Commons Attribution-ShareAlike 3.0 France.
Le shell permet de définir et réutiliser des variables :
$ message="hello world"
$ echo $message
hello world
Avertissement
Il ne faut pas d'espace autour du signe =
.
Note
Les guillemets sont nécessaires si la valeur de la variable contient des espaces
Le méta-caractère dollar ($
), suivi d'un nom de variable,
est remplacé par la valeur de la variable en question.
Cette substitution a lieu avant d'analyser les autres caractères. Ainsi, si la valeur de la variable contient des espaces, cela pourra donner lieu à plusieurs arguments dans la ligne de commande :
$ cp $message # copie le fichier 'hello' en 'world'
Important
Le méta-caractère dollar n'est pas inhibié par les guillemets doubles ("
).
En revanche, il l'est par les guillemets simples ('
).
$ echo "Simon says $message"
Simon says hello world
$ echo 'Simon says $message'
Simon says $message
Note
Si le nom utilisé après $ ne correspond à aucune variable définie, il est substitué par une chaîne vide (sans causer d'erreur).
La commande unset
suivi d'un nom de variable (sans le méta-caractère $
)
supprime la variable :
$ unset message
$ echo $message
$
Pour définir une variable d'environnement, il faut précéder son affectation du mot-clé export :
export MANPAGER=more
Note
Par convention, les variables d'environnement sont en majuscules, alors que les variables de shell sont en minuscules.
Les variables de shell
- sont gérées en interne par le shell ;
- ne sont pas accessible aux autres processus.
Les variables d'environnement
- sont gérées par le SE ;
- sont héritées par les processus lancés depuis le shell ;
- sont utilisées par certains programmes pour modifier leur comportement.
Exemple de configuration par l'environnement :
$ man ls # suivi de CTRL+Z
$ ps -H
PID TTY TIME CMD
28608 pts/4 00:00:00 bash
29162 pts/4 00:00:00 man
29172 pts/4 00:00:00 pager
29188 pts/4 00:00:00 ps
$ kill %1
$ export MANPAGER=more
$ man ls # suivi de CTRL+Z
$ ps -H
PID TTY TIME CMD
28608 pts/4 00:00:00 bash
29425 pts/4 00:00:00 man
29435 pts/4 00:00:00 more
29442 pts/4 00:00:00 ps
PATH
:
,
dans lesquels le shell cherche les programmes à lancerPS1
Note
La variable d'environnement PATH
ne contient pas le répertoire courant .
,
et ce pour des raisons de sécurité.
Cela évite de lancer par erreur un programme local nommé ls
ou cp
,
et qui pourrait avoir des effets inattendus (ou malicieux).
Affiche sur la sortie standard toutes les variables d'environnement actuellement définie.
Un ensemble de commandes shell peuvent être stockées dans un fichier, pour être réutilisées plus tard.
$ source commandes.sh
(sortie des instructions contenues dans commandes.sh)
$ . commandes.sh # '.' est équivalent à 'source'
(sortie des instructions contenues dans commandes.sh)
Execute dans le shell en cours les commandes contenues dans le fichier commandes.sh
.
Indication
Ce n'est pas la méthode la plus fréquente, notamment parce que les variables utilisées dans le fichier pourraient « polluer » le shell courant.
On l'utilise justement lorsque l'objectif est de modifier le shell courant ou les variables d'environnement.
La première ligne du fichier doit être #!/usr/bin/bash
.
L'utilisateur doit avoir les droits en exécution sur le fichier.
Le fichier peut alors être lancé comme n'importe quel programme :
$ ./commandes.sh
(sortie des instructions contenues dans commandes.sh)
Le shell exécutant les commande du script est un processus séparé du shell courant.
Note
/usr/bin/python
, /usr/bin/ruby
...Le caractère dièse (#
, plus exactement hash)
introduit un commentaire, ignoré par le shell.
Le commentaire s'étend jusqu'à la fin de la ligne.
$ echo texte affiché # commentaire non affiché
texte affiché
Note
Puisque le shebang commence par #, il est ignoré par le shell lui même, seul le SE l'interprète.
Lorsqu'on appelle un script (quelle que soit la méthode), on peut lui passer des arguments en ligne de commande.
Ces arguments sont accessibles dans des variables spéciales :
$1
, $2
, $3
... contiennent les différents arguments,$@
contient la séquence entière d'arguments.Rappel : tout processus lancé par un shell (y compris via un script) hérite de ses flux (entrée, sortie, erreur) standards.
Ainsi, les redirections appliquées à un script s'appliquent aux commandes lancées par ce script.
Contenu du fichier sort_column.sh
:
#!/usr/bin/bash
# extrait et trie une colonne
# des données passées sur l'entrée standard
cut -d: -f$1 | sort
Exemple d'utilisation:
$ ./sort_column.sh 1 </etc/passwd
Lit une ligne de texte sur l'entrée standard, et affecte le texte lu dans une ou plusieurs variable(s).
Par défaut, la lecture s'interromp au premier saut de ligne.
Retourne un succès si du texte est lu, un échec si la fin de fichier est rencontrée.
varname
Le texte lu est découpée au niveau des espaces ; la première variable reçoit le premier mot, la deuxième variable, le deuxième mot... et la dernière variable reçoit le reste du texte lu.
-n
[nchars]
Interromp la lecture au bout de nchars
caractères.
Note
Avec un seul nom de variable, l'intégralité du texte lu est affecté à cette variable.
Le shell fournit des structures de contrôles similaires à celles des langages de programmation.
if condition
then
commande 1
commande 2
# ...
else
commande 3
# ...
fi
Note
condition
est une ligne de commande ;
la valeur de retour
du processus détermine si c'est le then
(succès)
ou le else
(échec) qui sera exécuté.else
est facultative.fi
est formé comme l'inverse du mot-clé fi
.;
).Exemple :
if grep -q charlie </etc/passwd
then
echo "je l'ai trouvé"
fi
while condition
do
commande 1
commande 2
# ...
done
Note
if
,
le condition
est une ligne de commande.Exemple :
while read line
do
echo "Jacques a dit $line"
done
echo "Jacques a fini"
La commande cat
ré-écrit sur sa sortie standard le contenu de tous les fichiers qui lui sont passés en argument (son nom est une abbréviation de concatenate).
Boucle sur toutes les lignes d'un fichier :
cat my_file.txt | while read line
do
# do something with $line
done
for varname in liste de valeurs
do
commande 1
commande 2
done
Note
Exemple :
for i in A B C "D E F"
do
echo $i
done
Comme pour le reste,
les variables sont substituées avant l'analyse de la ligne,
donc une variable contenant plusieurs mots (séparés par des espaces)
peut être utilisée après le mot-clé in
.
for i in $valeurs
do
echo $i
done
On peut également utiliser la substitution par guillemets inversés.
for grp in `id -Gn`
do
echo "Vous appartenez au groupe $grp"
done
Avertissement
Attention avec ce dernier exemple ; il ne fonctionne pas comme attendu si certains éléments contiennent des espaces.
N'écrivez pas :
for filename in `ls`
do
cp $filename $filename.bak
done
Mais écrivez :
ls | while read filename
do
cp "$filename" "$filename.bak"
done
Note
ls
écrit un nom de fichier par ligne ;
ainsi, chaque nom de fichier sera lu en une fois par read
,
même s'il contient des espaces.
Cette précaution vaut bien sûr pour d'autres données, dont certaines lignes peuvent contenir des espaces.
La commande [ évalue une expression booléenne, décrite par ses arguments, et retourne un code de statut correspondant.
Le dernier argument doit être ]
.
NB: les espaces séparant les opérateurs et les opérandes sont indispensable,
pour que le shell les transmette à la commande [
comme des arguments séparés.
STRING1 = STRING2
Vrai si les deux chaînes sont égales.
STRING != STRING2
Vrai si les deux chaînes sont différentes.
INTEGER1 -lt INTEGER2
Vrai si les deux opérandes sont des entiers, et que INTEGER1 est strictement inférieur à INTEGER2.
Existent également -le
(≤), -gt
(>), -ge
(≥).
-f FILENAME
Vrai si FILENAME est le nom d'un fichier classique existant.
-d FILENAME
Vrai si FILENAME est le nom d'un répertoire existant.
EXPR1 -a EXPR2
Vrai si les deux expressions sont vraies.
EXPR2 -o EXPR2
Vrai si l'une au moins des deux expressions est vraie.
! EXPR
Vrai si EXPR est fausse.
Pour une documentation exhaustive, tapez man [
.
Exemple :
#!/usr/bin/bash
if [ -d "$1" -a -f "$2" ]
then
cp "$2" "$1"/"$2".bak
else
echo "Invalid arguments" >&2
exit 1
fi
Note
>&2
est une redirection particulière,
qui redirige la sortie standard vers l'erreur standard.
Elle permet ici d'utiliser echo
pour écrire sur l'erreur standard
(alors que son comportement normal est décrire sur la sortie standard).
exit <integer>
sort immédiatement du script,
en retournant la valeur passée en argument.exit
sort du script avec la valeur de retour de la dernière commande exécutée.|| exit
.