Table des matières
Résumé
Dans ce module d'introduction nous
Décrivons quelques Shell courants
Mettons en avant les avantages et possibilités du Bash GNU
Décrivons les blocs de constructions du Shell
Abordons les fichiers d'initialisation du Bash
Voyons comment le Shell exécute les commandes
Examinons quelques exemples simples de scripts
Le programme Shell UNIX interprète les ordres de contrôle, qu'ils soient donnés par l'utilisateur, ou qu'ils soient lus depuis un fichier appelé script Shell ou programme Shell. Les scripts Shell sont interprétés, et non pas compilés. Le Shell lit les commandes du script ligne par ligne et recherche ces commandes dans le système (voir Section 2, « Avantages du Bourne Again SHell »), tandis que le compilateur convertit un programme sous une forme exploitable par la machine, un fichier exécutable - lequel peut être alors à son tour utilisé dans un script.
A part de passer des commandes au noyau, la tâche principale du Shell est de mettre en place un environnement utilisateur qui peut être configuré individuellement par le biais de fichiers de configuration.
De même que les gens peuvent parler plusieurs langues, votre système UNIX offre en principe différents Shell.
sh ou Bourne Shell: le Shell originel toujours en vigueur sur les systèmes UNIX et sur les environnements de type UNIX. C'est le Shell de base, un petit programme avec peu de possibilités. Bien que ce ne soit pas le Shell standard, il est toujours disponible sur les systèmes Linux par souci de compatibilité des programmes UNIX.
bash ou Bourne Again shell: le Shell standard GNU , intuitif et souple. Probablement celui à conseiller aux débutants tout en étant un outil puissant pour un usage poussé et professionnel. Sur Linux, bash est le Shell standard pour l'utilisateur courant. Ce Shell est réputé être un sur-ensemble du Bourne Shell, un ensemble d'ajouts et d'extensions. Ce qui veut dire que le Bourne Again Shell est compatible avec le Bourne Shell: les commandes reconnues par sh, le sont aussi par bash. Cependant, l'inverse n'est pas toujours vrai. Tous les exemples et exercices de ce livre utilisent bash.
csh ou C shell: la syntaxe de ce Shell ressemble à celle du langage de programmation C. Parfois demandée par certains programmeurs.
tcsh ou Turbo C shell: un sur-ensemble du classique C shell, ajoutant convivialité et rapidité.
ksh ou le Korn shell: quelques fois apprécié des gens venant du monde UNIX. Un sur-ensemble du Bourne Shell; avec une configuration - le cauchemar des débutants - standard.
Le fichier /etc/shells donne une vue d'ensemble des Shells connus sur un système Linux:
mia:~>
cat /etc/shells
/bin/bash
/bin/sh
/bin/tcsh
/bin/csh
Le Shell par défaut est déclaré dans le fichier /etc/passwd, comme cette ligne pour l'utilisateur mia:
mia:L2NOfqdlPrHwE:504:504:Mia Maya:/home/mia:/bin/bash
Pour activer un autre Shell, il suffit de taper le nom de ce Shell sur la ligne de commande. Le système localise le répertoire où apparaît le nom du nouveau Shell en utilisant la déclaration PATH, et comme le Shell est un fichier exécutable (un programme), le Shell courant le lance et rend actif le nouveau Shell. Une nouvelle invite est souvent affichée, du fait que chaque Shell a une interface propre:
mia:~>
tcsh
[mia@post21 ~]$
Le projet GNU (ne pas confondre GNU et UNIX) offre des outils pour l'administration de système de type UNIX qui sont libres et qui respectent les standards UNIX.
Bash est un Shell compatible avec sh qui incorpore des fonctionnalités pratiques du Korn shell (ksh) et du C shell (csh). Il est censé se conformer à la norme IEEE POSIX P1003.2/ISO 9945.2 Standards des Shell et Outils. Il offre des améliorations fonctionnelles par rapport à sh pour la programmation et l'utilisation interactive; ce qui inclut l'édition de commande en ligne, historique illimité des commandes, contrôle des travaux, fonctions Shell et alias, tableau indexé de taille illimitée, et l'arithmétique d'entiers dans toutes les bases depuis la base 2 jusqu'à la base 64. Bash peut exécuter la plupart des scripts sh sans modification.
Comme les autres projets GNU, le projet bash a été lancé pour préserver, protéger et promouvoir la liberté d'utiliser, étudier, copier, modifier et redistribuer les logiciels. Il est généralement admis que de telles conditions stimulent la créativité. Cela a été le cas avec le programme Bash, qui a beaucoup de fonctionnalités que les autres Shells n'offrent pas.
En plus de la possibilité de commandes sur 1 caractère qui peut être en général configurée en utilisant la commande intégrée set, il y a plusieurs options multi-caractères disponibles. Nous verrons une partie des options les plus usitées dans ce chapitre et les suivants; la liste complète se trouve dans les pages info de Bash, → .
Les fichiers de démarrage sont des scripts lus et exécutés par Bash quand il est initialisé. La sous-section suivante décrit diverses façons de démarrer le Shell, et les fichiers de démarrage lus en conséquence.
Interactif signifie que vous pouvez entrer des commandes. Le Shell n'est pas lancé parce qu'un script a été activé. Un Shell de connection vous donne accès au Shell après qu'il vous ait authentifié, généralement en contrôlant le nom d'utilisateur et le mot de passe.
Fichiers lus:
/etc/profile
~/.bash_profile, ~/.bash_login ou ~/.profile: le premier fichier lisible trouvé est lu
~/.bash_logout à la déconnexion.
Des messages d'erreur s'affichent si les fichiers de configuration existent mais sont illisibles. Si un fichier n'existe pas, Bash cherche le suivant.
Un Shell sans connexion ne demande pas d'authentification. Par exemple, quand vous ouvrez un terminal en activant une icône, ou un choix de menu, c'est un Shell sans connexion.
Fichiers lus:
~/.bashrc
Ce fichier est habituellement référencé dans ~/.bash_profile:
if [ -f ; then . ~/.bashrc ]~/.bashrc; fi
Voir Chapitre 7, Les instructions de condition pour plus d'informations sur la construction if.
Tout script utilise un Shell non-interactif. Ils sont programmés pour faire certaines tâches et ne peuvent être utilisés pour faire autre chose que ce pour quoi ils ont été prévus.
Fichiers lus:
définis par la variable BASH_ENV
PATH n'est pas utilisé pour la recherche de ces fichiers, donc indiquez leur chemin complet dans la variable si vous souhaitez en faire usage.
Bash essaye de se comporter comme le programme historique Bourne sh tout en se conformant au standard POSIX également.
Fichiers lus:
/etc/profile
~/.profile
En mode interactif la variable ENV fournit des informations de démarrage supplémentaires.
Cette option est activée soit en utilisant la commande intégrée set:
set -o posix
soit en appelant le Bash avec l'option --posix. Bash essayera alors de respecter autant que possible la norme POSIX des Shell. Déclarer la variable POSIXLY_CORRECT donne le même résultat.
Fichiers lus:
définis par la variable ENV
Fichiers lus quand le Shell est invoqué par rshd:
~/.bashrc
Gardez à l'esprit les dangers d'outils tels que rlogin, telnet, rsh et rcp. Leur usage présente des risques pour la confidentialité et la sécurité de par leur mode d'accès parce que des données non cryptées parcourent le réseau. Si vous avez le besoin d'outils à distance, transfert de fichiers et autres, utilisez une version de Secure SHell, c'est à dire SSH, disponible gratuitement ici: http://www.openssh.org. Divers programmes client sont également disponibles pour les systèmes non-UNIX, consulter votre miroir de logiciels.
Un Shell interactif lit généralement depuis, et écrit sur, un terminal utilisateur: entrée et sortie sont reliées à un terminal. Le mode interactif de Bash est activé quand la commande bash est invoquée sans les options rendant inactif, et sauf avec l'option qui permet de prendre l'entrée depuis une chaîne de caractères ou quand le Shell est invoqué de façon à lire l'entrée standard, ce qui autorise les paramètres positionnels (voir Chapitre 3, L'environnement du Bash ).
Test en examinant le paramètre spécial -, il contient un 'i' quand le Shell est interactif:
eddy:~>
echo $-
himBH
Dans un Shell non interactif, l'invite PS1, n'est pas paramétrée.
Différences en mode interactif:
Bash lit les fichiers de démarrage.
Le contrôle de travail est actif par défaut.
Les invites sont paramétrées, PS2 est paramétré pour les commandes multi-lignes, il est habituellement paramétré à « > ». C'est aussi l'invite que l'on obtient quand le Shell trouve que la commande entrée est incomplète, par exemple si vous oubliez des guillemets, une structure de commande non terminée, etc.
Les commandes sont par défaut lues depuis la ligne de commande en utilisant readline.
Bash interprète l'option Shell ignoreeof plutôt que de sortir immédiatement à la réception de EOF (Fin de Fichier).
L'historique des commandes avec leur expansion est activé par défaut. L'historique est enregistré dans le fichier désigné par HISTFILE, quand le Shell se termine. Par défaut, HISTFILE pointe sur ~/.bash_history.
L'expansion d'alias est actif.
En l'absence de 'trap', le signal SIGTERM est ignoré.
En l'absence de 'trap', SIGINT est capturé et exploité. Donc, les touches Ctrl+C, par exemple, ne feront pas quitter votre Shell interactif.
Le signal SIGHUP est configuré pour être envoyé à tous les travaux quand Bash se termine, avec l'option huponexit .
Les commandes sont exécutées à la lecture.
Bash vérifie régulièrement le courrier électronique.
Bash peut être configuré pour quitter quand il trouve des variables non déclarées. En mode interactif ce comportement est désactivé.
Quand les commandes intégrées du Shell trouvent des erreurs de redirection, cela n'a pas pour effet de quitter le Shell.
Les commandes intégrées utilisées selon le mode POSIX et qui renvoient des erreurs n'ont pas pour effet de quitter le Shell. Les commandes intégrées sont listées à la Section 3, « L'exécution de commandes ».
Un échec de exec ne fait pas quitter le Shell.
Des erreurs produites par l'analyse de syntaxe ne font pas quitter le Shell.
Le contrôle simple de nom des arguments de la commande intégrée cd est activé par défaut.
La sortie automatique, après le laps de temps spécifié par la variable TMOUT, est activée.
Plus d'informations:
Voir Chapitre 12, Trapper les signaux au sujet des signaux.
Section 4, « Le processus d'expansion de Shell » aborde divers processus d'expansion sur une commande saisie.
Les expressions de conditions emploient la commande composée [[ et les commandes intégrées test et [.
Les expressions peuvent être unaire ou binaire. Une expression unaire est souvent utilisée pour examiner le statut d'un fichier. Vous avez seulement besoin d'un objet, par exemple un fichier, pour tester une condition dessus.
Il y a aussi des opérateurs de comparaison de textes et de nombres; ils sont binaires, puisqu'ils requièrent 2 objets pour effectuer le test. Si l'option FICHIER d'une expression est de la forme /dev/fd/N, alors le descripteur de fichier N est utilisé. Si l'option FICHIER d'une expression est de la forme /dev/stdin, /dev/stdout ou /dev/stderr, alors le descripteur de fichier 0, 1 ou 2 respectivement est utilisé.
Les conditions sont discutées en détail au Chapitre 7, Les instructions de condition.
Plus d'informations au sujet des descripteurs de fichiers à la Section 2.3, « Redirection et descripteurs de fichiers ».
Le shell autorise l'évaluation des expressions arithmétiques soit par l'expansion, soit par la commande intégrée let.
L'évaluation utilise des entiers de longueur fixe sans vérification de possible débordement de capacité, mais avec un contrôle de la division par 0 qui renvoie une erreur. Les opérateurs, leur ordre et leur associativité, sont pareils que dans le langage C, voir Chapitre 3, L'environnement du Bash.
Un alias permet de substituer un mot à une chaîne de caractère quand il est utilisé comme premier mot d'une commande simple. Le Shell maintient une liste d'alias qui sont déclarés ou invalidés avec les commandes alias et unalias.
Bash lit toujours au moins une ligne complète saisie avant d'exécuter une des commandes de cette ligne. L'alias est interprété quand la commande est lue, non pas quand elle est exécutée. De ce fait, une définition d'alias apparaissant sur la même ligne qu'une autre commande ne prendra effet qu'à la lecture de la ligne suivante. Les commandes suivant la définition de l'alias sur la ligne ne seront pas affectées par le nouvel alias.
Un alias est interprété quand la définition d'une fonction est lue, pas quand la fonction est exécutée, parce que la définition de fonction est elle-même une commande composée. En conséquence, l'alias définit dans une fonction n'est pas utilisable tant que la fonction n'a pas été exécutée.
Nous aborderons les alias en détail à la Section 5, « Alias ».
Bash offre des variables-tableau à une dimension. Toute variable peut être utilisée en tant que tableau; la commande intégrée declare declare un tableau explicitement. Il n'y a pas de limite supérieure à la taille d'un tableau, ni de besoin de trier ou d'assigner de façon contiguë les valeurs. Les tableaux sont basés sur le zéro. Voir Chapitre 10, Un peu plus sur les variables.
La pile de répertoires est une liste des répertoires récemment accédés. La commande intégrée pushd empile les répertoires tout en changeant le répertoire courant, et popd dépile le répertoire spécifié tout en changeant le répertoire courant pour celui dépilé.
Le contenu peut être afficher avec la commande dirs ou en visualisant le contenu de la variable DIRSTACK.
Plus d'informations au sujet du fonctionnement de ces mécanismes se trouvent dans les pages Bash info.
Bash permet de jouer avec l'invite de façon amusante. Voir la section Controlling the Prompt dans les pages Bash info.
Invoqué avec rbash ou avec l'option --restricted ou -r il se produit ce qui suit:
La commande intégrée cd est indisponible.
Déclarer ou invalider les variables SHELL, PATH, ENV ou BASH_ENV n'est pas possible.
Les noms de commande ne peuvent plus comporter de slashes.
Les noms de fichiers comprenant un slash ne sont plus admis par la commande intégrée . (source).
L'intégrée hash n'accepte pas le slash avec l'option -p .
L'import de fonctions au démarrage est désactivé.
SHELLOPTS est ignoré au démarrage.
La redirection des résultats avec >, >|, ><, >&, &> et >> est désactivée.
La commande intégrée exec est indisponible.
L'option -f et -d sont désactivées pour l'intégrée enable.
Un chemin par défaut PATH ne peut pas être spécifié avec l'intégrée command.
Annuler le mode restrictif n'est pas possible.
Quand une commande qui appele un script Shell est exécutée, rbash annule toute restriction dans le Shell lancé dans lequel s'exécute ce script.
Plus d'informations:
Bash détermine le type de programme qui est à exécuter. Les programmes standards sont les commandes système qui existent sous forme compilée dans le système. Quand un tel programme est exécuté, un nouveau processus est crée parce que Bash lance une copie exacte de lui-même. Ce processus fils a le même environnement que son parent, seul l'identifiant est différent. Cette procédure est appelée forking(NdT: fourcher).
Une fois que le processus a fourché, l'espace d'adresse du processus fils est renseigné avec ses propres informations. Ceci est fait grâce à un appel système par exec.
Le mécanisme fork-and-exec interrompt une commande en cours pour une autre, tandis que l'environnement dans lequel ce nouveau programme est exécuté reste le même, ce qui inclut la configuration des périphériques d'entrée/sortie, les variables d'environnement et les priorités. Ce mécanisme est utilisé pour créer tous les processus UNIX, donc il est appliqué aussi par le système d'exploitation de Linux. Même le premier processus, init, avec l'identifiant 1, fourche pendant le démarrage dans la procédure appelée bootstrapping.
Les commandes intégrées sont incorporées dans le Shell lui-même. Quand le nom d'une commande intégrée est employé comme le premier mot d'une commande simple, le Shell exécute la commande directement, sans créer un nouveau processus. Les commandes intégrées sont nécessaires pour implanter des fonctionnalités impossibles ou difficiles à mettre en oeuvre par des outils externes. (NdT: dans la suite de ce document nous parlerons de façon elliptique d'intégrée pour dire commande intégrée)
Bash possède 3 types de commandes intégrées:
Celles de Bourne Shell:
:, ., break, cd, continue, eval, exec, exit, export, getopts, hash, pwd, readonly, return, set, shift, test, [, times, trap, umask et unset.
Celles de Bash:
alias, bind, builtin, command, declare, echo, enable, help, let, local, logout, printf, read, shopt, type, typeset, ulimit et unalias.
Les spéciales:
Quand Bash est exécuté en mode POSIX, les commandes spéciales diffèrent des autres selon 3 aspects:
Les commandes spéciales sont rencontrées avant les fonctions Shell pendant la localisation de la commande.
Si une commande spéciale renvoie un statut en erreur, un Shell non-interactif quitte.
Les variables affectées avant la commande existent toujours dans l'environnement Shell après que la commande se soit terminée.
Les commandes spéciales POSIX sont :, ., break, continue, eval, exec, exit, export, readonly, return, set, shift, trap et unset.
La plupart de ces intégrées seront abordées dans les chapitres suivants. Pour les commandes qui ne le seront pas, se référer aux pages Info.
Quand le programme à exécuter est un script Shell, Bash crée un nouveau processus Bash en fourchant. Ce sous-Shell lit les lignes du script une par une. Les commandes de chaque ligne sont lues, interprétées et exécutées comme si elles avaient été entrées au clavier.
Tandis que le sous-Shell opère sur chaque ligne du script, le Shell parent attend que le processus fils ait fini. Quand il n'y a plus de ligne à lire dans le script, le sous-Shell se termine. Le Shell parent s'active et affiche l'invite de nouveau.
Si à la lecture du texte le Shell ne reconnaît pas un commentaire, il divise en mots et opérateurs en utilisant les règles de syntaxe pour déterminer la signification de chaque caractère entré. Alors ces mots et opérateurs sont transformés en commandes et autres constructions, lesquels retournent un statut d'exécution qui peut être exploité. Le procédé 'fork-and-exec' présenté auparavant est mis en oeuvre seulement après que le Shell ait analysé la saisie de la façon suivante:
Le Shell lit le texte en entrée dans un fichier, ou une chaîne (de caractère), ou depuis le périphérique de saisie.
Le texte est découpé en mots et opérateurs, selon les règles de syntaxe, voir Chapitre 3, L'environnement du Bash. Ces éléments sont séparés par des métacaractères. Les alias sont remplacés par leur équivalent.
Le Shell analyse et transforme les éléments en commandes simples ou composées.
Bash procède à diverses expansions d'éléments, les décomposant en listes de fichiers et commandes avec arguments.
Au besoin il est procédé à des redirections, les opérateurs de redirection et leurs opérandes sont éliminés de la liste des arguments.
Les commandes sont exécutées.
Optionnellement le Shell attend que la commande s'achève pour récupérer son statut d'exécution.
Une simple commande Shell telle que touch file1
file2
file3
consiste en la commande elle-même suivie d'arguments, séparés par des espaces.
Les commandes Shell plus complexes sont des compositions variées de commandes simples: en tube lequel délivre le résultat d'une commande sur le canal d'entrée de la suivante, en boucle ou en construction de conditions, et encore d'autres façons. Quelques exemples:
ls | more
gunzip file.tar.gz | tar xvf
-
La fonction Shell est le moyen de grouper des commandes en vue d'une exécution ultérieure par l'appel du seul nom de la fonction. Elle est exécutée tout comme une commande « ordinaire ». Quand le nom de la fonction Shell est employé comme le nom d'une commande simple, la liste des commandes associées à cette fonction est exécutée.
Les fonctions Shell sont exécutées dans le contexte en cours du Shell, elles ne sont pas interprétées dans un nouveau processus.
Les fonctions sont expliquées au Chapitre 11, Fonctions.
Un paramètre est une entité qui mémorise une valeur. Cela peut être un nom, un nombre ou une valeur spéciale. Pour les besoins du Shell, une variable est un paramètre que mémorise un nom. Une variable a une valeur et zéro ou plus attributs. Une variable est créé avec la commande intégrée Shell declare.
Si aucune valeur ne lui est assignée, une variable prend la valeur nulle. Une variable peut être invalidée seulement avec l'intégrée unset.
L'assignation de variables est traitée à la Section 2, « Variables », utilisation poussée de variables au Chapitre 10, Un peu plus sur les variables.
L'expansion est opérée par Shell après que chaque ligne de commande ait été découpée en éléments. Voici les opérations d'expansion:
L'expansion d'accolades
L'expansion du tilde
L'expansion de paramètres et de variables
La substitution de commande
L'expansion arithmétique
Le découpage de mots
L'expansion de nom de fichiers
Nous traiterons ces types d'expansion à la Section 4, « Le processus d'expansion de Shell ».
Avant qu'une commande soit exécutée, son entrée et sa sortie peuvent être redirigées par le moyen de symboles interprétés par Bash. La redirection peut aussi être employée pour ouvrir et fermer des fichiers dans l'environnement d'exécution du Shell.
A l'exécution d'une commande, les mots que l'analyse syntaxique a marqué comme assignation de variables (précédant le nom de commande) et comme redirection sont conservés pour y faire référence ultérieurement. Les autres mots sont interprétés (expansion); le premier mot qui subsiste après l'expansion est réputé être le nom de la commande et le reste ses arguments. Alors les opérations de redirections sont effectuées, puis les valeurs assignées aux variables sont interprétées (expansion). Si le résultat ne donne aucun nom de commande, les variables sont affectées dans l'environnement en cours.
Une part importante du travail du Shell est de localiser les commandes. Bash le fait de cette façon:
Recherche du caractère slash dans la commande. Si aucun, d'abord parcourir la liste de fonctions pour voir si elle contient le nom de commande cherché.
Si la commande n'est pas une fonction, la chercher dans la liste des intégrées.
Si la commande n'est ni une fonction ni une intégrée, la chercher dans les répertoires donnés par la variable PATH. Bash utilise une table hachée (stockée en mémoire) pour mémoriser le chemin exact des exécutables de sorte qu'une analyse de chaque répertoire du PATH est évitée.
Si la recherche est un échec, Bash affiche un message d'erreur et retourne le statut d'exécution 127.
Si la recherche donne un résultat ou si la commande contient des slashs, le Shell exécute la commande dans un environnement d'exécution propre.
Si l'exécution échoue parce que le fichier n'est pas exécutable et qu'il n'est pas un répertoire, il est alors considéré comme étant un script Shell.
Si la commande n'a pas été lancée de façon asynchrone, le Shell attend que la commande se termine et récupère son statut d'exécution.
Quand un fichier contenant des commandes Shell est placé comme un argument de type paramètre (par opposition à une option) à l'invocation de Bash(sans -c ou -s) un Shell non-interactif est lancé. Ce Shell cherche d'abord le fichier de script dans le répertoire en cours, puis cherche dans ceux de PATH si le fichier ne peut pas y être trouvé.
Ce guide porte principalement sur les scripts (la dernière construction de blocs évoquée précédemment). Voyons quelques considérations générales avant de continuer:
Un script devrait s'exécuter sans erreurs.
Il devrait accomplir la tâche pour laquelle il a été conçu.
La logique du programme est clairement définie et apparente.
Un script n'exécute pas des instructions inutiles.
Les scripts devraient être réutilisables.
La structure d'un script Shell est vraiment adaptable. Même si Bash permet beaucoup de liberté, vous devez mettre en oeuvre une logique rigoureuse, un contrôle des données, une efficacité qui permet à l'utilisateur qui exécute le script de le faire facilement et correctement.
Au moment d'écrire un nouveau script, posez-vous les questions suivantes:
Aurai-je besoin d'informations de la part de l'utilisateur ou de son environnement?
Comment vais-je mémoriser ces données?
Des fichiers doivent-ils être créés? Où et avec quel propriétaire et quelles permissions?
Quelles commandes utiliserai-je? Si le script est exécuté sur différents systèmes, est-ce que tous ces systèmes ont les commandes dans la version requise?
L'utilisateur a-t'il besoin que le script lui renvoie des informations? Quand et pourquoi?
La table ci-dessous donne une vue générale des termes de programmation que vous avez besoin de connaître:
Tableau 1.1. Vue générale des termes de programmation
| Termes | Qu'est-ce que c'est? |
|---|---|
| Contrôle de commande | Test du statut d'exécution (NdT: code retour) d'une commande pour déterminer si une portion du code doit être exécutée ou pas. |
| Branchement conditionnel | Une instruction logique du programme qui détermine quelle alternative du programme exécuter ensuite. |
| Enchaînement logique | La conception du programme dans ses grandes lignes. Détermine la séquence logique des opérations de sorte que cela aboutisse à un résultat contrôlé. |
| Boucle | Partie de code qui s'exécute zéro fois ou plus. |
| Saisie de l'utilisateur | Donnée fournie par une source externe (NdT périphérique de saisie) pendant que le programme tourne, qui peut être mémorisée et exploitée au besoin. |
De façon à abréger l'étape de développement, l'enchaînement logique d'un programme devrait être pensé à l'avance. C'est votre première étape quand vous développez un script.
Diverses méthodes peuvent être utilisées; une des plus courantes est la constitution de listes. Lister les opérations nécessaires au programme vous permet de décrire chaque tâche. Les opérations unitaires peuvent être référencées par leur numéro dans la liste.
En utilisant vos propres mots pour déterminer les opérations à exécuter par votre programme il vous sera plus facile de créer un programme compréhensible. Ensuite, vous écrivez le langage compris par Bash.
L'exemple ci-dessous montre un tel enchaînement logique. Il décrit la rotation des fichiers journaux. Cet exemple montre la possible réitération d'une boucle, en fonction du nombre de fichiers journaux sur lesquels vous voulez paramétrer une rotation.
Voulez-vous paramétrer la rotation de journaux?
Si oui:
Indiquez le répertoire contenant les journaux sur lesquels la rotation se fera.
Entrez le nom générique du fichier journal.
Entrez le nombre de jours durant lesquels le journal doit être conservé.
Enregistrer le paramétrage dans le fichier utilisateur 'crontab'.
Si non, aller à l'étape 3.
Voulez-vous paramétrer la rotation d'un autre ensemble de journaux?
Si oui: répéter étape 1.
Si non, aller à l'étape 3.
Fin
L'utilisateur va devoir saisir des données pour que le programme effectue quelque chose. La saisie de l'utilisateur doit être sollicitée et mémorisée. L'utilisateur devrait être informé que 'son' crontab va être changé.
Le script mysystem.sh ci-dessous exécute des commandes bien connues (date, w, uname, uptime) pour afficher des informations au sujet de la machine et sur vous.
tom:~>
cat -n
mysystem.sh
1 #!/bin/bash
2 clear
3 echo "Ce sont des informations fournies par mysystem.sh. Le programme démarre maintenant."
4
5 echo "Bonjour, $USER"
6 echo
7
8 echo "Nous sommes le `date`, semaine `date +"%V"`."
9 echo
10
11 echo "Ces utilisateurs sont actuellement connectés:"
12 w | cut -d " " -f 1 - | grep -v USER | sort -u
13 echo
14
15 echo "`uname -s` est le système, `uname -m` le processeur."
16 echo
17
18 echo "Le système fonctionne depuis:"
19 uptime
20 echo
21
22 echo "C'est pas plus compliqué!"
Un script commence toujours par ces 2 caractères: « #! ». Suit le nom du Shell qui exécutera les commandes suivant. Ce script commence en effaçant l'écran à la ligne 2. La ligne 3 fait afficher un message pour informer l'utilisateur de ce qui va se passer. La ligne 5 salue l'utilisateur. Les lignes 6, 9, 13, 16 et 20 ne sont là que pour aérer l'affichage des résultats. La ligne 8 affiche la date du jour et le numéro de la semaine. Ligne 11 encore un message informatif, ainsi que ligne 3, 18 et 22. La ligne 12 formate le résultat de la commande w; la ligne 15 affiche le nom du système d'exploitation et le type de processeur. La ligne 19 donne la durée de fonctionnement du système ainsi que sa charge.
echo et printf sont des commandes intégrées de Bash. La première retourne toujours un statut à 0, et affiche simplement ses arguments terminés par un caractère de fin de ligne sur la sortie standard, tandis que la deuxième autorise des options de formatage de la chaîne et renvoie un statut différent de 0 en cas d'échec.
Voici le même script avec l'intégrée printf:
tom:~>
cat mysystem.sh
#!/bin/bash
clear
printf "Ce sont des informations fournies par mysystem.sh. Le programme démarre maintenant."
printf "Bonjour, $USER.\n\n"
printf "Nous sommes le `date`, semaine `date +"%V"`.\n\n"
printf "Ces utilisateurs sont actuellement connectés:\n"
w | cut -d " " -f 1 - | grep -v USER | sort -u
printf "\n"
printf "`uname -s` est le système, `uname -m` le processeur.\n\n"
printf "Le système fonctionne depuis:\n"
uptime
printf "\n"
printf "C'est pas plus compliqué\n"
L'écriture d'un script convivial en insérant des messages est traité au Chapitre 8, Ecrire des scripts interactifs.
Ceci implique que le programme bash est installé dans /bin.
Si vous exécutez un script par cron, pensez à fournir le chemin complet et à rediriger les résultats et les erreurs. Du fait que le Shell tourne en mode non-interactif, toute erreur provoquera la fin du script prématurément si vous n'y songez pas.
Les chapitres suivants traiteront en détail les scripts ci-dessus.
Un init script démarre les services des systèmes UNIX et Linux. Les démons de journalisation du système, de gestion des ressources, de contrôle d'accès et de mails en sont des exemples. Ces scripts, appelés aussi scripts de démarrage, sont stockés à un endroit spécifique du système, tel que dans /etc/rc.d/init.d ou /etc/init.d. Init, le processus initial, lit ses fichiers de configuration et décide quels services il démarre ou arrête en fonction du niveau d'exécution système. Le niveau d'exécution est un état de configuration du système (NdT qui correspond à une utilisation particulière du système); chaque système a un niveau d'exécution qui autorise un unique utilisateur, par exemple, pour exécuter des tâches administratives, pour lesquelles le système doit être dans un état aussi stable que possible. Comme récupérer un fichier système important depuis une sauvegarde. Les niveaux d'exécution de démarrage et d'arrêt sont habituellement aussi configurés.
Les tâches à exécuter au démarrage ou à l'arrêt d'un service sont listées dans le script de lancement. C'est l'une des tâches de l'administrateur système de configurer init, de façon que les services soient lancés et stoppés au bon moment. Quand vous êtes confrontés à cette tâche, vous avez besoin d'une bonne compréhension des procédures de démarrage et d'arrêt du système. Nous vous conseillons donc de lire les pages man pour init et inittab avant de vous lancer dans les scripts d'initialisation.
Voici un très simple exemple, qui jouera un son au démarrage et à l'arrêt de votre machine:
#!/bin/bash # This script is for /etc/rc.d/init.d # Link in rc3.d/S99audio-greeting and rc0.d/K01audio-greeting case "$1" in 'start') cat /usr/share/audio/at_your_service.au > /dev/audio ;; 'stop') cat /usr/share/audio/oh_no_not_again.au > /dev/audio ;; esac exit 0
L'instruction case souvent utilisée dans ce genre de script est décrite à la Section 2.5, « Emploi de l'instruction exit et du if ».
Bash est le Shell GNU, compatible avec Bourne shell, il incorpore beaucoup de fonctionnalités pratiques issues d'autres Shells. Quand le Shell est lancé, il lit ses fichiers de configuration. Les plus importants sont:
/etc/profile
~/.bash_profile
~/.bashrc
Bash agit différemment en mode interactif; il a un mode à la norme POSIX et un autre restreint.
Les commandes Shell peuvent être classées en 3 groupes: les fonctions Shell, les intégrées Shell et les commandes réparties dans les répertoires du système. Bash admet des intégrées supplémentaires qui ne sont pas connues du classique Bourne Shell.
Les scripts Shell comportent ces commandes agencées selon la syntaxe dictée par Shell. Les scripts sont lus et exécutés ligne par ligne et devraient avoir une structure logique.
Ces exercices vont vous entraîner pour le prochain chapitre:
Où le programme bash est localisé sur le système?
Utilisez l'option --version pour déterminer quelle version vous utilisez.
Quels fichiers de configuration du Shell sont lus quand vous vous faites authentifier par le système par le moyen de l'interface graphique puis en ouvrant une fenêtre de console?
Les Shell suivants sont-ils interactifs? Sont-ils des Shell d'authentification?
Un Shell ouvert en cliquant dans l'arrière plan de votre bureau graphique sur l'icône « Terminal » ou l'équivalent dans un menu.
Un Shell activé avec la commande ssh localhost
.
Un Shell que vous activez en vous connectant à la console en mode texte.
Un Shell activé par la commande xterm &.
Un Shell activé par le script mysystem.sh.
Un Shell que vous activez sur un système distant, pour lequel vous n'aviez pas besoin de vous authentifier parce que vous utilisez SSH et peut être des clés SSH.
Pouvez-vous expliquer pourquoi bash ne quitte pas quand vous frappez les touches Ctrl+C sur la ligne de commande?
Faites afficher le contenu de la pile des répertoires.
Si ce n'est pas déjà le cas, paramétrez l'invite de sorte qu'elle affiche votre localisation dans la hiérarchie système, par exemple ajoutez cette ligne à ~/.bashrc:
export PS1="\u@\h \w> "
Affichez les commandes mémorisées dans la table 'hash' de votre session de Shell en cours.
Combien de processus sont en train de tourner sur votre système? Utilisez ps et wc, la première ligne de résultat de ps n'est pas un processus!
Comment afficher le nom du système? Seulement le nom, rien de plus!