Vous utilisez tous (peut être sans le savoir) le shell bash. Dans cet article vous allez apprendre un certain nombre d'astuces qui vous permettrons d'utiliser au mieux ce programme. C'est l'occasion pour les nouveaux venus à Linux d'apprendre et aux vieux routards de rafraîchir leurs souvenirs.
Le shell sert d'interface entre le système d'exploitation et
l'utilisateur. Pour les utilisateurs qui sont venus récemment à
Linux, le shell est cette fenêtre principalement utilisée
pour lancer les commandes en mode texte. Pour les "vieux de la vieille",
le shell est l'unique, la vraie, la seule interface possible entre le noyau
et l'utilisateur ;-)
Avant la généralisation d'interfaces graphiques comme
GNOME ou KDE, les utilisateurs n'avaient guère d'autres possibilités
pour exécuter une commande que d'utiliser un shell. Aujourd'hui,
cette interface a tendance à être considérée
comme obsolète et la plupart des nouveaux utilisateurs n'en connaissent
pas toutes les subtilités. Cet article tente de réparer cette
injustice malheureuse.
Historiquement, le premier shell est dû à Steve Bourne au début des années 1970. Un certain nombre d'autres shells ont depuis été écrits, mais le plus courrament utilisé aujourd'hui est GNU bash (pour 'Bourne Again SHell'). Il existe bien d'autres programmes ayant à peu de choses près les mêmes fonctionnalités (ash, zsh, tcsh, pdksh, etc), mais bash étant installé par défaut sur tous les systèmes Linux, c'est celui-ci que nous allons étudier de plus près.
Maitrisez l'historique
Bash contient un mécanisme d'hishorique extremement pratique. Lancez simplement un shell, soit en vous loggant sur le système si vous étes en mode texte, soit en cliquant dans votre barre de menu sur l'icône qui représente soit un coquillage (si vous utilisez KDE), soit un pingouin à coté d'un écran (si vous utilisez GNOME).
Il est souvent pénible d'avoir à taper plusieurs fois
de suite quasiment la même commande à cause d'une faute de
frappe. Pour cela, bash offre un mécanique d'historique qui permet
d'éditer les commandes déjà entrées. Cet historique
peut être utilisé grâce à plusieurs méthodes.
Voyons de plus près chacune d'entre elles.
La méthode de gestion d'historique la plus simple utilise les
fléches de directions. Essayez d'entrer successivement les trois
commandes suivantes dans un shell :
cd /
ls -al /etc/passwd
tail /etc/resolv.conf
Maintenant tapez sur la flèche curseur 'haut'. La dernière
commande est apparue au prompt du shell. Tapez encore sur la fléche
'haut' et c'est la commande ls qui devrait la remplacer. Pour
repasser à la commande suivante, tapez sur la fléche 'bas'.
Il vous suffit maintenant de taper sur entrée pour réexécuter
cette commande. Notons au passage que dans le cas où vous ne voulez
ou ne pouvez pas utiliser les fléches 'haut' et 'bas', vous pouvez
utiliser à la place les combinaisons de touches Ctrl-P
(pour "Previous command") et Ctrl-N (pour "Next command").
En plus de cette méthode séquentielle pour "reprendre"
des commandes, il existe un moyen d'effectuer une recherche dans les commandes
effectuées. Pour essayer cette méthode, tapez Ctrl-R.
Le prompt a été remplacé par la chaine (reverse-i-search)`'.
Si vous desirez retrouver la dernière commande qui contient la chaine
'etc', il vous suffit de taper cette chaîne et la commande 'tail
/etc/resolv.conf' apparaitra. A ce stade, vous pouvez soit décider
d'exécuter à nouveau cette commande en tapant sur entrée,
soit decider que vous vous vouliez en fait la dernière commande
opérant sur le fichier /etc/passwd. Dans ce dernier cas,
il suffit de continuer à taper, donc d'ajouter '/p', et
déjà le prompt devrait à la place montrer la commande
ls
-al /etc/passwd.
Bash permet également de référencer les commandes
par numéro d'ordre.
Pour vous en convaincre, exécutez la commande "history".
Celle-ci affiche la liste des dernières commandes utilisées.
Il est possible que cette instruction liste des commandes qui ont été
utilisées lors de sessions précédentes. En effet,
bash enregistre la liste des commandes tapées durant la session
dans un fichier ".bash_history" situé dans le répertoire
racine de l'utilisateur. Pour rappeler une commande, il suffit d'entrer
son numéro d'ordre précédé d'un point d'exclamation.
Par exemple, "!30" rappelle la trentième commande. Il est
également possible d'utiliser la syntaxe '!!' pour demander
la réexécution de la dernière commande entrée.
Ce mécanisme d'historique permet également de ne récupérer
que certains paramétres des dernières commandes :
# cat ~/articles/bash.html ~/articles/py4.html
[...]
# vi !-1:2
Cette dernière notation indique à bash qu'il doit exécuter la commande 'vi' suivie du deuxième paramétre de la derniere commande.
L'utilisateur averti pourra parfois avoir envie d'utiliser son éditeur
favori (que ce soit vim ou emacs) pour éditer la ligne de commande.
Cela est fort heureusement possible grâce à la commande 'fc'.
Celle-ci peut être utilisée avec plusieurs paramètres
différents qui permettent de gérer au mieux l'historique
de votre session en cours. Notons au passage que 'fc' n'est pas une commande
que vous pourrez trouver sur votre disque dur, c'est une commande interne
("built-in") du shell, au même titre que 'cd' par exemple.
fc peut être invoqué aussi bien pour lister une partie
de l'historique :
fc -l -20 : affiche les 20 dernières commandes.
que pour l'éditer :
fc -e vi : édite la dernière commande tapée avec
vi et exécute la commande modifiée lors de la sortie de l'éditeur.
D'autre part, l'éditeur utilisé par fc par défaut
peut être spécifié une fois pour toutes en donnant
à la variable FCEDIT le nom de votre éditeur de
prédilection.
Écrivez vos propres scripts
Si vous avez tendance à utiliser souvent la même séquence
de commandes, l'écriture d'un script peut se réveler plus
pratique que d'utiliser le mécanisme d'historique. Un script est
tout simplement une liste de commandes shell enregistrées dans un
fichier qui seront exécutées ensemble lorsque le script sera
appelé. Commençons par un exemple simple; supposons que vous
désiriez écrire un script qui soit capable de remplacer une
chaîne de caractères donnée par une autre dans un fichier
texte.
Commencez par enregistrer les lignes suivantes à l'aide de votre
éditeur de texte favori dans un fichier nommé 'script.sh'
:
#!/bin/sh
cp $1 /tmp/replace.$$
sed -e "s/$2/$3/g" < /tmp/replace.$$ > $1
Puis exécutez la commande 'chmod +x script.sh' pour rendre le script directement exécutable.
Pour le tester, créez un fichier 'test.txt' contenant simplement
la ligne de texte :
Red Hat est la meilleure distribution Linux!
Maintenant, testons si notre programme fonctionne correctement :
# ./script.sh test.txt "Red Hat" Debian
# cat test.txt
Debian est la meilleure distribution Linux!
#
Ça marche! ;-)
Examinons maintenant le code de notre script plus en détail :
La première ligne indique au noyau le nom de l'interpréteur
à utiliser pour exécuter le script, en l'occurence /bin/sh
qui est un lien vers /bin/bash.
La deuxième ligne est utilisée pour faire une copie de
notre fichier d'origine. A l'exécution, les variables $1, $2,
$3, etc sont substituées par les premier, deuxième et
troisième paramètres passés sur la ligne de commande.
La variable $$ est également spéciale : celle-ci
correspond au numéro de processus (PID) de l'instance du shell qui
exécutera le script. Cette variable est très souvent utilisée,
comme elle l'est ici, pour déterminer un nom de fichier temporaire.
La troisième et dernière ligne est celle qui fait réellement
ce que l'on attend du script, à savoir le remplacement de chaînes.
Le fichier temporaire est utilisé comme source de données
et le résultat de la substitution et remis dans le fichier d'origine.
Nous allons maintenant essayer de rendre ce script un peu plus robuste. En effet, si le nombre de paramètres passés est incorrect ou s'il y a une erreur lors de la création du fichier temporaire, l'erreur ne sera pas correctement détectée ce qui risque de laisser l'utilisateur perplexe dans la mesure ou l'absence de message d'erreur est censé indiquer un bon déroulement des opérations.
Pour commencer, nous devons nous assurer que le nombre de paramètres passés au script est bien correct.
Nous allons préalablement définir une fonction dont le but est d'afficher un message mentionnant les paramètres attendus par le programme et de terminer l'exécution du script.
usage() {
echo "Usage : script.sh fichier.txt chaine1
chaine2"
exit -1
}
Maintenant, on teste que les 3 paramètres existent et on exécute la fonction usage le cas échéant.
[ -z "$1" -o -z "$2" -o -z "$3" ] && usage
Comme vous l'avez probablement déjà deviné, l'opérateur '-o' correspond au "ou logique", alors que '-z' retourne la valeur vraie si la chaîne de caractères qui suit est vide.
Maintenant, pour que notre programme soit vraiment beau, il ne reste
plus qu'à définir le nom du fichier temporaire dans une variable,
plutôt que de le désigner directement chaque fois que l'on
en a besoin. En effet, une des règles de base de la programmation
stipule qu'une définition ne doit jamais être faite à
deux endroits différents, ou si vous préférez, vous
devez "factoriser" votre code le plus possible.
Cela se fait simplement en ajoutant la définition suivante au
début du script :
tmp=/tmp/replace.$$
et par la suite on utilise $tmp pour faire référence
au nom du fichier temporaire.
Nous devons également tester qu'il n'existe pas déjà
un fichier ayant le même nom.
Pour cela, on effectue un test avec l'opérateur '-e'
qui teste l'existence d'un fichier :
if [ -e "$tmp" ]
then
echo "Le fichier $tmp existe deja."
exit -1
fi
Enfin, la touche finale : on ajoute l'instruction 'set -e' au début du script pour qu'il s'interrompe dès qu'une commande retourne une valeur de retour non nulle, ce qui indique son échec (par exemple, l'impossibilité de créer le fichier temporaire dans l'éventualité de l'échec de la commande 'cp').
Et voici la version finale de notre script :
#!/bin/sh
tmp=/tmp/replace.$$
if [ -f "$tmp" ]
then
echo "le fichier $tmp
existe deja."
exit -1
fi
usage() {
echo Usage : script.sh
fichier.txt chaine1 chaine2
exit -1
}
[ -z "$1" -o -z "$2" -o -z "$3" ] && usage
cp $1 $tmp
sed -e "s/$2/$3/g" < $tmp > test2.txt
Voilà, maintenant vous devriez en savoir assez pour être
à l'aise avec la ligne de commande, ainsi qu'être capable
d'écrire vos propres programmes shell pour réaliser des tâches
simples. Si vous désirez en savoir plus sur le sujet (que nous n'avons
qu'effleuré ici), vous pourrez consulter les documents cités
en références. Bons scripts!
|
Bash-Prog-Intro-HOWTO :
http://www.linuxdoc.org/HOWTO/Bash-Prog-Intro-HOWTO.html Bash2 reference manual : http://www.svn.net/helpdesk/bashref.html |
Utilisateur de GNU/Linux depuis 1993, Vincent Renardias
est activement impliqué dans son développement depuis 1996
: Développeur de la distribution Debian, auteur de la traduction
Française de l'environnement GNOME, créateur du groupe d'utilisateurs
Linux de Marseille (PLUG). Il continue aujourd'hui activement a promouvoir
le système GNU/Linux en tant que responsable technique de la société
Echo (créatrice du moteur de recherche www.voila.fr).
Vincent Renardias <vincent@echo.fr> |
Copyright (c) 2001 Linux Magazine France. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; A copy of the license is included in the section entitled "GNU Free Documentation License".