<chapter id="chap_01"><title>Bash et scripts Bash</title>
<abstract>
<para>Dans ce module d'introduction nous</para>
<para><itemizedlist>
<listitem><para>Décrivons quelques Shell courants</para></listitem>
<listitem><para>Mettons en avant les avantages et possibilités du Bash GNU</para></listitem>
<listitem><para>Décrivons les blocs de constructions du Shell</para></listitem>
<listitem><para>Abordons les fichiers d'initialisation du Bash</para></listitem>
<listitem><para>Voyons comment le Shell exécute les commandes</para></listitem>
<listitem><para>Examinons quelques exemples simples de scripts</para></listitem>
</itemizedlist></para>
</abstract>

<sect1 id="sect_01_01"><title>Les langages de contrôle (Shell) courants</title>
<sect2 id="sect_01_01_01"><title>Les fonctions du Shell en général</title>
<para>Le Shell UNIX<indexterm><primary>shell</primary><secondary>general functions</secondary></indexterm> interprète les commandes de l'utilisateur, qui sont soit directement entrées par celui-ci, ou qui peuvent être lues depuis un fichier appelé un script shell ou programme. Ces scripts sont interprétés, donc non compilés.  Le Shell lit les commandes de chaque ligne du script et cherche ces commandes dans le système (voir <xref linkend="sect_01_02" />), alors qu'un compilateur convertit un programme en une forme lisible par la machine, un fichier exécutable - lequel peut alors être employé dans un script.</para>
<para>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.</para>
</sect2>

<sect2 id="sect_01_01_02"><title>Types de Shell</title>
<para>Tout comme les gens connaissent une variété de langages, votre système UNIX généralement offre une variété de types de Shell <indexterm><primary>shell</primary><secondary>types</secondary></indexterm>&nbsp;:</para>
<itemizedlist>
<listitem><para><command>sh</command> ou Bourne Shell&nbsp;: 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.</para></listitem>
<listitem><para><command>bash</command> ou Bourne Again shell&nbsp;: 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, <command>bash</command> est le Shell standard pour l'utilisateur courant. Ce Shell est réputé être un <emphasis>sur-ensemble</emphasis> 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&nbsp;: les  commandes reconnues par <command>sh</command>, le sont aussi par 
<command>bash</command>. Cependant, l'inverse n'est pas toujours vrai. Tous les exemples et exercices de ce livre utilisent <command>bash</command>.</para></listitem>
<listitem><para><command>csh</command> ou C shell&nbsp;: la syntaxe de ce Shell ressemble à celle du langage de programmation C.  Parfois demandée par les programmeurs.</para></listitem>
<listitem><para><command>tcsh</command> ou TENEX C Shell&nbsp;: un surensemble du répandu Shell C, implémentant convivialité et rapidité.  C'est pourquoi certains l'appellent aussi le Turbo Shell C.</para></listitem>
<listitem><para><command>ksh</command> ou le Korn shell&nbsp;: quelques fois apprécié des 
gens venant du monde UNIX.  Un sur-ensemble du Bourne Shell&nbsp;; avec une configuration - le cauchemar des débutants -  standard.</para></listitem>
</itemizedlist>

<para>Le fichier <filename>/etc/shells</filename> donne un aperçu des Shells connus du système Linux <indexterm><primary>fichier de configuration</primary><secondary>/etc/shells</secondary></indexterm>&nbsp;:</para>
<screen>
<prompt>mia:~&gt;</prompt> <command>cat <filename>/etc/shells</filename></command>
/bin/bash
/bin/sh
/bin/tcsh
/bin/csh
</screen>
<para>Votre Shell par défaut est déclaré dans le fichier <filename>/etc/passwd</filename> <indexterm><primary>fichier de configuration</primary><secondary>/etc/passwd</secondary></indexterm>, comme cette ligne pour l'utilisateur <emphasis>mia</emphasis>&nbsp;:</para>
<screen>
mia:L2NOfqdlPrHwE:504:504:Mia Maya:/home/mia:/bin/bash
</screen>
<para>Pour permuter d'un<indexterm><primary>shell</primary><secondary>permuter entre Shells</secondary></indexterm> Shell à un autre, simplement entrez le nom du nouveau Shell actif dans le terminal.  Le système trouve le répertoire où le nom apparaît au moyen des paramètres de <varname>PATH</varname>, et puisqu'un Shell est un fichier exécutable (programme), le Shell courant l'active et il s'exécute. Une nouvelle invite est souvent affichée, du fait que chaque Shell a une interface propre&nbsp;:</para>
<screen>
<prompt>mia:~&gt;</prompt> <command>tcsh</command>
[mia@post21 ~]$
</screen>
</sect2>

</sect1>

<sect1 id="sect_01_02"><title>Avantages du Bourne Again SHell</title>
<sect2 id="sect_01_02_01"><title>Bash est le Shell GNU</title>
<para>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.</para>
<para>Bash<indexterm><primary>Bash</primary><secondary>advantages</secondary></indexterm> est un Shell compatible avec sh qui incorpore des spécificités utiles 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&nbsp;; 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.</para>
<para>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.</para>
</sect2>

<sect2 id="sect_01_02_02"><title>Fonctionnalités offertes seulement par le Bash</title>
<sect3 id="sect_01_02_02_01"><title>Invocation</title>
<para>En plus<indexterm><primary>Bash</primary><secondary>features</secondary></indexterm> de l'option permettant des commandes Shell à un caractère qui peut être configuré généralement avec la commande intégrée  <command>set</command>, il y a plusieurs options multi-caractères que vous pouvez employer.  Nous verrons quelques unes de ces options les plus usitées<indexterm><primary>features</primary><secondary>invocation</secondary></indexterm> dans les chapitres suivants&nbsp;; la liste complète peut être trouvée dans les pages info de Bash, <menuchoice><guimenu>Bash features</guimenu><guimenuitem>Invoking Bash</guimenuitem></menuchoice>.</para>
</sect3>

<sect3 id="sect_01_02_02_02"><title>Fichiers de démarrage de Bash</title>
<para>Les fichiers de démarrage<indexterm><primary>Bash</primary><secondary>startup files</secondary></indexterm> sont des scripts qui sont lus et exécutés par Bash quand il démarre.  Les sous-sections suivantes<indexterm><primary>features</primary><secondary>startup files</secondary></indexterm> décrivent diverses façons de démarrer le Shell, et le fichier de démarrage lu en conséquence.</para> 
<sect4 id="sect_01_02_02_02_01"><title>Invoqué pour être le Shell d'interaction, ou avec l'option `--login'</title>
<para>Interactif<indexterm><primary>invocation</primary><secondary>interactive login shell</secondary></indexterm> 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.</para>
<para>Fichiers lus&nbsp;:</para>
<itemizedlist>
<listitem><para><filename>/etc/profile</filename></para></listitem>
<listitem><para><filename>~/.bash_profile</filename>, <filename>~/.bash_login</filename> ou <filename>~/.profile</filename>&nbsp;: le premier fichier lisible trouvé est lu</para></listitem>
<listitem><para><filename>~/.bash_logout</filename> à la déconnexion.</para></listitem>
</itemizedlist>
<para>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.</para>
</sect4>

<sect4 id="sect_01_02_02_02_02"><title>Invoqué comme Shell interactif sans étape de connexion</title>
<para>Un Shell sans connexion<indexterm><primary>invocation</primary><secondary>interactive non-login shell</secondary></indexterm> signifie que l'accès ne nécessite pas d'authentification par le système. Par exemple, quand vous ouvrez un terminal par le biais d'une icone, ou d'un menu.</para>
<para>Fichiers lus&nbsp;:</para>
<itemizedlist>
<listitem><para><filename>~/.bashrc</filename></para></listitem>
</itemizedlist>

<para>Ce fichier est habituellement référencé dans <filename>~/.bash_profile</filename>&nbsp;:</para>
<cmdsynopsis><command>if <function>[ -f <filename>~/.bashrc</filename> ]</function>; then . <filename>~/.bashrc</filename>; fi</command></cmdsynopsis>

<para>Voir <xref linkend="chap_07" /> pour plus d'informations sur la construction <command>if</command>.</para>
</sect4>

<sect4 id="sect_01_02_02_02_03"><title>Invoqué non interactivement</title>
<para>Tous les scripts utilisent un Shell  non-interactif<indexterm><primary>invocation</primary><secondary>non-interactive</secondary></indexterm>. 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.</para>
<para>Fichiers lus&nbsp;:</para>
<itemizedlist>
<listitem><para>définis<indexterm><primary>variables</primary><secondary>BASH_ENV</secondary></indexterm> par <varname>BASH_ENV</varname></para></listitem>
</itemizedlist>
<para><varname>PATH</varname> n'est pas utilisé pour la recherche de ces fichiers, donc mettre le chemin complet dans la variable si vous souhaitez en faire usage.</para>
</sect4>

<sect4 id="sect_01_02_02_02_04"><title>Invoqué avec la commande sh</title>

<para>Bash<indexterm><primary>invocation</primary><secondary>invoked as sh</secondary></indexterm> essaye de se comporter comme le programme historique Bourne <command>sh</command> tout en se conformant à la norme POSIX.</para>
<para>Fichiers lus&nbsp;:</para>
<itemizedlist>
<listitem><para><filename>/etc/profile</filename></para></listitem>
<listitem><para><filename>~/.profile</filename></para></listitem>
</itemizedlist>
<para>Quand il est invoqué de façon interactive, la variable <varname>ENV</varname> <indexterm><primary>variables</primary><secondary>ENV</secondary></indexterm> peut pointer vers des informations de démarrage suplémentaires.</para>
</sect4>

<sect4 id="sect_01_02_02_02_05"><title>Mode POSIX</title>
<para>Cette option<indexterm><primary>invocation</primary><secondary>POSIX mode</secondary></indexterm> est activée soit en employant l'intégrée <command>set</command>&nbsp;:</para>
<cmdsynopsis><command>set <option>-o posix</option></command></cmdsynopsis>
<para>ou en appelant le <command>Bash</command> avec l'option <option>--posix</option> option.  Bash essayera alors de respecter autant que possible la norme POSIX des Shell.  Déclarer la variable <varname>POSIXLY_CORRECT</varname> <indexterm><primary>variables</primary><secondary>POSIXLY_CORRECT</secondary></indexterm> fait la même chose.</para>
<para>Fichiers lus&nbsp;:</para>
<itemizedlist>
<listitem><para>définis par la variable <varname>ENV</varname></para></listitem>
</itemizedlist>
</sect4>
<sect4 id="sect_01_02_02_02_06"><title>Invoqué à distance</title>

<para>Fichiers lus quand le Shell est invoqué par<indexterm><primary>invocation</primary><secondary>remote invocation</secondary></indexterm> <command>rshd</command>&nbsp;:</para>
<itemizedlist>
<listitem><para><filename>~/.bashrc</filename></para></listitem>
</itemizedlist>
<warning><title>Eviter l'usage d'outils à distance</title>
<para>Ayez à l'esprit les dangers de ces outils tels que <command>rlogin</command>, <command>telnet</command>, <command>rsh</command> et <command>rcp</command>.  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&nbsp;: <ulink url="http://www.openssh.org">http://www.openssh.org</ulink>.  Divers programmes client sont disponibles aussi pour les systèmes non-UNIX, consulter votre miroir de logiciels.</para>
</warning>
</sect4>
<sect4 id="sect_01_02_02_02_07"><title>Invoqué alors que UID est différent de EUID</title>

<para>Aucun fichier de démarrage<indexterm><primary>invocation</primary><secondary>UID &lt;&gt; EUID</secondary></indexterm> n'est lu dans ce cas.</para>

</sect4>

</sect3>
<sect3 id="sect_01_02_02_03"><title>Shell interactif</title>
<sect4 id="sect_01_02_02_03_01"><title>Qu'est-ce qu'un Shell interactif</title>
        <para>Un Shell interactif<indexterm><primary>shell</primary><secondary>interactive</secondary></indexterm> généralement lit et écrit depuis et sur un terminal utilisateur&nbsp;: les flux d'entrée et de sortie sont dirigés vers le terminal. Le mode interactif de Bash<indexterm><primary>features</primary><secondary>interactive shells</secondary></indexterm> est activé quand la commande <command>bash</command> 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 <xref linkend="chap_03" /> ).</para>
</sect4>
<sect4 id="sect_01_02_02_03_02"><title>Ce Shell est-il interactif&nbsp;?</title>
<para>Test en examinant la variable spéciale <varname>-</varname>, il contient un 'i' quand le Shell est interactif&nbsp;:</para>
<screen>
<prompt>eddy:~&gt;</prompt> <command>echo <varname>$-</varname></command>
himBH
</screen>
<para>Dans un Shell non interactif, l'invite <varname>PS1</varname>, n'est pas paramétrée.</para>
</sect4>
<sect4 id="sect_01_02_02_03_03"><title>Le comportement d'un Shell interactif</title>
<para>Différences dans le mode interactif<indexterm><primary>interactive shell</primary><secondary>behavior</secondary></indexterm>&nbsp;:</para>
<itemizedlist>
<listitem><para>Bash lit les fichiers de démarrage.</para></listitem>
<listitem><para>Le contrôle de travail est actif par défaut.</para></listitem>
<listitem><para>Les invites sont établies, <varname>PS2</varname> est déclaré pour des commandes multi-lignes<indexterm><primary>variables</primary><secondary>PS2</secondary></indexterm> , il est souvent déclaré à <quote>&gt;</quote>.  C'est aussi l'invite que l'on obtient quand le Shell trouve que la commande entrée n'est pas finie, par exemple si vous oubliez des guillemets, une structure de commande non finie, etc.</para></listitem>
<listitem><para>Les commandes sont par défaut lues depuis la ligne de commande en utilisant <command>readline</command>.</para></listitem>
<listitem><para>Bash interprète l'option Shell  <option>ignoreeof<indexterm><primary>options</primary><secondary>ignoreeof</secondary></indexterm></option> plutôt que de sortir immédiatement à la réception de EOF (Fin de Fichier).</para></listitem>
<listitem><para>L'historique des commandes avec leur expansion est activé par défaut.  L'historique est enregistré dans le fichier désigné par<indexterm><primary>variables</primary><secondary>HISTFILE</secondary></indexterm> <varname>HISTFILE</varname> quand le Shell est quitté.  Par defaut, <varname>HISTFILE</varname> pointe vers <filename>~/.bash_history</filename>.</para></listitem>
<listitem><para>L'expansion d'alias est actif.</para></listitem>
<listitem><para>En l'absence de 'trap', le signal  <option>SIGTERM</option> est ignoré.</para></listitem>
<listitem><para>En l'absence de 'trap',  <option>SIGINT</option> est capturé et exploité.  Donc, les touches <keycap>Ctrl</keycap>+<keycap>C</keycap>, par exemple, ne feront pas quitter votre Shell interactif.</para></listitem>
<listitem><para>Le signal <option>SIGHUP</option> est configuré pour être envoyé à tous les travaux quand Bash se termine, avec l'option <option>huponexit</option> option.</para></listitem>
<listitem><para>Les commandes sont exécutées à la lecture.</para></listitem>
<listitem><para>Bash vérifie régulièrement le courrier électronique.</para></listitem>
<listitem><para>Bash peut être configuré pour quitter quand il trouve des variables non déclarées.  En mode interactif ce comportement est désactivé.</para></listitem>
<listitem><para>Quand les commandes intégrées du Shell trouvent des erreurs de redirection, cela n'a pas pour effet de quitter le Shell.</para></listitem>
<listitem><para>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 <xref linkend="sect_01_03_02" />.</para></listitem>
<listitem><para>Un échec de <command>exec</command> ne fait pas quitter le Shell.</para></listitem>
<listitem><para>Des erreurs produites par l'analyse de syntaxe ne font pas quitter le Shell.</para></listitem>
<listitem><para>Le contrôle simple de nom des arguments de la commande intégrée <command>cd</command> est activé par défaut.</para></listitem>
<listitem><para>La sortie automatique, après le laps de temps spécifié par la variable <varname>TMOUT</varname>, est activée.</para></listitem>
</itemizedlist>
<para>Plus d'informations&nbsp;:</para>

<itemizedlist>
<listitem><para><xref linkend="sect_03_02" /></para></listitem>
<listitem><para><xref linkend="sect_03_06" /></para></listitem>
<listitem><para>Voir <xref linkend="chap_12" /> au sujet des signaux.</para></listitem>
<listitem><para><xref linkend="sect_03_04" /> aborde divers processus d'expansion sur une commande saisie.</para></listitem>
</itemizedlist>


</sect4>

</sect3>
<sect3 id="sect_01_02_02_04"><title>Les conditions</title>
        <para>Les expressions conditionnelles<indexterm><primary>features</primary><secondary>conditionals</secondary></indexterm> sont utilisées dans la commande composée <command>[[</command> et par les intégrées <command>test</command> et <command>[</command>.</para>
<para>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, exemple un fichier, pour tester une condition dessus.</para>
<para>Il y a aussi des opérateurs de comparaison de textes et de nombres&nbsp;; ils sont binaires, puisqu'ils requièrent 2 objets pour effectuer le test.  Si l'option <option>FICHIER</option>  d'une expression est de la forme <filename>/dev/fd/N</filename>, alors le descripteur de fichier N est utilisé.  Si l'option <option>FICHIER</option> d'une expression est de la forme <filename>/dev/stdin</filename>, <filename>/dev/stdout</filename> ou <filename>/dev/stderr</filename>, alors le descripteur de fichier 0, 1 ou 2 respectivement est utilisé.</para>
<para>Les conditions sont discutées en détail au <xref linkend="chap_07" />.</para>
<para>Plus d'informations au sujet des descripteurs de fichiers à la <xref linkend="sect_08_02_03" />.</para>
</sect3>
<sect3 id="sect_01_02_02_05"><title>L'arithmétique avec Shell</title>
<para>Le Shell permet aux expressions arithmétiques<indexterm><primary>features</primary><secondary>shell arithmetic</secondary></indexterm> d'être évaluées, en tant que processus d'expansion ou par l'intégrée <command>let</command>.</para>
<para>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 pareil que dans le langage C, voir  <xref linkend="chap_03" />.</para>
</sect3>
<sect3 id="sect_01_02_02_06"><title>Alias</title>
<para>Les alias<indexterm><primary>features</primary><secondary>aliases</secondary></indexterm> permettent à une chaîne d'être substituée par un mot quand il est utilisé comme le premier mot d'une commande simple.  Le Shell maintient une liste d'alias qui peuvent être déclarés ou supprimés avec les commandes  <command>alias</command> et <command>unalias</command>.</para>

<para>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.</para>
<para>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éfini dans une fonction n'est pas utilisable tant que la fonction n'a pas été exécutée.</para>
<para>Nous aborderons les alias en détail à la <xref linkend="sect_03_05" />.</para>
</sect3>
<sect3 id="sect_01_02_02_07"><title>Tableaux</title>
<para>Bash fournit les variables sous la forme d'un tableau à une dimension<indexterm><primary>features</primary><secondary>arrays</secondary></indexterm> .  Toute variable peut être utilisée comme un tableau&nbsp;; l'intégrée <command>declare</command> déclarera explicitement un tableau.  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 <xref linkend="chap_10" />.</para>
</sect3>
<sect3 id="sect_01_02_02_08"><title>Pile de répertoires</title>
<para>La pile de répertoires<indexterm><primary>features</primary><secondary>directory stack</secondary></indexterm> est une liste des répertoires récemment visités.  L'intégrée <command>pushd</command><indexterm><primary>built-ins</primary><secondary>pushd</secondary></indexterm> ajoute des répertoires à la pile tout en changeant le répertoire courant, et l'intégrée <command>popd</command> <indexterm><primary>built-in</primary><secondary>popd</secondary></indexterm> enlève les répertoires spécifiés de la pile en positionant le répertoire courant comme étant celui qui vient d'être enlevé.</para>
<para>Le contenu peut être affiché avec la commande <command>dirs</command> ou en visualisant la variable <varname>DIRSTACK<indexterm><primary>variables</primary><secondary>DIRSTACK</secondary></indexterm></varname>.</para>
<para>Plus d'informations au sujet du fonctionnement de ces mécanismes se trouvent dans les pages Bash info.</para>
</sect3>
<sect3 id="sect_01_02_02_09"><title>L'invite</title>
<para>Bash permet de jouer avec l'invite<indexterm><primary>features</primary><secondary>prompt</secondary></indexterm> de façon amusante.  Voir la section <emphasis>Controlling the Prompt</emphasis> dans les pages info de Bash.</para>
</sect3>
<sect3 id="sect_01_02_02_10"><title>Le Shell restreint</title>
<para>Quand il est invoqué avec <command>rbash<indexterm><primary>features</primary><secondary>restricted shell</secondary></indexterm></command> ou avec <option>--restricted<indexterm><primary>options</primary><secondary>restricted</secondary></indexterm></option> ou l'option <option>-r</option> , il se produit ceci<indexterm><primary>restricted shell</primary><secondary>behavior</secondary></indexterm>&nbsp;:</para>
<itemizedlist>
<listitem><para>La commande intégrée <command>cd</command> est indisponible.</para></listitem>
<listitem><para>Déclarer ou invalider <varname>SHELL<indexterm><primary>variables</primary><secondary>SHELL</secondary></indexterm></varname>, <varname>PATH<indexterm><primary>variables</primary><secondary>PATH</secondary></indexterm></varname>, <varname>ENV<indexterm><primary>variables</primary><secondary>ENV</secondary></indexterm></varname> ou <varname>BASH_ENV<indexterm><primary>variables</primary><secondary>BASH_ENV</secondary></indexterm></varname> n'est pas possible.</para></listitem>
<listitem><para>Les noms de commande ne peuvent plus comporter de slashes.</para></listitem>
<listitem><para>Un nom de fichier contenant un slash n'est pas permis avec l'intégrée <command>.</command> (<command>source</command>)<indexterm><primary>built-ins</primary><secondary>source</secondary></indexterm> .</para></listitem>
<listitem><para>L'intégrée <command>hash</command><indexterm><primary>built-ins</primary><secondary>hash</secondary></indexterm> n'accepte pas des slashs avec l'option <option>-p</option>.</para></listitem>
<listitem><para>L'Import de fonctions<indexterm><primary>functions</primary><secondary>restricted shell</secondary></indexterm> au démarrage est désactivé.</para></listitem>
<listitem><para><varname>SHELLOPTS<indexterm><primary>variables</primary><secondary>SHELLOPTS</secondary></indexterm></varname> est  ignoré au démarrage.</para></listitem>
<listitem><para>La redirection des résultats avec <command>&gt;</command>, <command>&gt;|</command>, <command>&gt;&lt;</command>, <command>&gt;&amp;</command>, <command>&amp;&gt;</command> et <command>&gt;&gt;</command> est désactivée.</para></listitem>
<listitem><para>La commande intégrée <command>exec</command> est indisponible.</para></listitem>
<listitem><para>L'option <option>-f</option>  et  <option>-d</option> Les options sont désactivées pour l'intégrée <command>enable</command> <indexterm><primary>built-ins</primary><secondary>enable</secondary></indexterm>.</para></listitem>
<listitem><para>Un chemin par défaut <varname>PATH</varname> ne peut pas être spécifié avec l'intégrée <command>command</command>.</para></listitem>
<listitem><para>Annuler le mode restrictif n'est pas possible.</para></listitem>
</itemizedlist>
<para>Quand une commande qui appele un script Shell est exécutée, <command>rbash</command> annule toute restriction dans le Shell lancé dans lequel s'exécute ce script.</para>
<para>Plus d'informations&nbsp;:</para>

<itemizedlist>
<listitem><para><xref linkend="sect_03_02" /></para></listitem>
<listitem><para><xref linkend="sect_03_06" /></para></listitem>
<listitem><para><menuchoice><guimenu>Info Bash</guimenu><guisubmenu>Basic Shell Features</guisubmenu><guimenuitem>Redirections</guimenuitem></menuchoice></para></listitem>
<listitem><para><xref linkend="sect_08_02_03" />&nbsp;: redirection poussée</para></listitem>
</itemizedlist>

</sect3>

</sect2>

</sect1>

<sect1 id="sect_01_03"><title>L'exécution de commandes</title>
<sect2 id="sect_01_03_01"><title>Généralité</title>
<para>Bash determine le type de programme qui doit être exécuté<indexterm><primary>commands</primary><secondary>execution</secondary></indexterm>.  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éé 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 appellée <emphasis>forking</emphasis>.</para>
<para>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 <emphasis>exec</emphasis>.</para>
<para>Le mécanisme <emphasis>fork-and-exec</emphasis> <indexterm><primary>commands</primary><secondary>fork-and-exec</secondary></indexterm> cependant substitue une ancienne commande par une nouvelle, tandis que l'environnement dans lequel le nouveau programme est exécuté reste le même, y compris la configuration des entrées/sorties, des variables d'environnement et des priorités.  Ce mécanisme est employé pour créer tous les processus UNIX, donc il s'applique aussi au système d'opération Linux. Même le premier processus, <command>init</command>, avec l'ID 1, fourche dans la procédure de démarrage appelée <emphasis>bootstrapping</emphasis>.</para>
</sect2>
<sect2 id="sect_01_03_02"><title>Les commandes intégrées du Shell</title>
<para>Les commandes intégrées<indexterm><primary>commands</primary><secondary>built-in commands</secondary></indexterm> sont parties intégrantes du 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.</para>
<para>Bash possède 3 types de commandes intégrées&nbsp;:</para>
<itemizedlist>
<listitem><para>Les intégrées Bourne<indexterm><primary>built-ins</primary><secondary>Bourne Shell built-ins</secondary></indexterm>&nbsp;:</para>
<para><command>:</command>, <command>.</command>, <command>break</command>, <command>cd</command>, <command>continue</command>, <command>eval</command>, <command>exec</command>, <command>exit</command>, <command>export</command>, <command>getopts</command>, <command>hash</command>, <command>pwd</command>, <command>readonly</command>, <command>return</command>, <command>set</command>, <command>shift</command>, <command>test</command>, <command>[</command>, <command>times</command>, <command>trap</command>, <command>umask</command> et <command>unset</command>.</para>
</listitem>
<listitem><para>Les intégrées Bash<indexterm><primary>built-ins</primary><secondary>Bash built-ins</secondary></indexterm>&nbsp;:</para>
<para><command>alias</command>, <command>bind</command>, <command>builtin</command>, <command>command</command>, <command>declare</command>, <command>echo</command>, <command>enable</command>, <command>help</command>, <command>let</command>, <command>local</command>, <command>logout</command>, <command>printf</command>, <command>read</command>, <command>shopt</command>, <command>type</command>, <command>typeset</command>, <command>ulimit</command> et <command>unalias</command>.</para>
</listitem>
<listitem><para>Les intégrées speciales<indexterm><primary>built-ins</primary><secondary>special built-ins</secondary></indexterm>&nbsp;:</para>
<para>Quand Bash est exécuté en mode POSIX, les commandes spéciales diffèrent des autres selon 3 aspects&nbsp;:</para>
<orderedlist>
<listitem><para>Les commandes spéciales sont rencontrées avant les fonctions Shell pendant la localisation de la commande.</para></listitem>
<listitem><para>Si une commande spéciale renvoie un statut en erreur, un Shell non-interactif quitte.</para></listitem>
<listitem><para>Les variables affectées avant la commande existent toujours dans l'environnement Shell après que la  commande se soit terminée.</para></listitem>
</orderedlist>
<para>Les commandes spéciales POSIX sont <command>:</command>, <command>.</command>, <command>break</command>, <command>continue</command>, <command>eval</command>, <command>exec</command>, <command>exit</command>, <command>export</command>, <command>readonly</command>, <command>return</command>, <command>set</command>, <command>shift</command>, <command>trap</command> et <command>unset</command>.</para>
</listitem>
</itemizedlist>
<para>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.</para>
</sect2>
<sect2 id="sect_01_03_03"><title>Exécuter un programme dans un script.</title>
<para>Quand le programme<indexterm><primary>commands</primary><secondary>script execution</secondary></indexterm> en exécution est un script Shell, Bash créera un nouveau processus Bash en activant un <emphasis>fork</emphasis>.  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.</para>
<para>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.</para>
</sect2>

</sect1>
<sect1 id="sect_01_04"><title>Construction de blocs</title>
<sect2 id="sect_01_04_01"><title>Construction de blocs Shell</title>
<sect3 id="sect_01_04_01_01"><title>La syntaxe Shell</title>
<para>Si la saisie n'est pas commentée, le Shell la  lit<indexterm><primary>shell</primary><secondary>syntax</secondary></indexterm> et la divise en mots et opérateurs, selon les règles d'analyse qui déterminent la signification de chaque caractère saisi.  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 schéma fork-and-exec ci-dessus est appliqué seulement après que le Shell ait analysé la saisie selon le processus suivant<indexterm><primary>input</primary><secondary>analysis</secondary></indexterm>&nbsp;:</para>
<itemizedlist>
<listitem><para>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.</para></listitem>
<listitem><para>Le texte est découpé en mots et opérateurs, selon les règles de syntaxe, voir <xref linkend="chap_03" />.  Ces éléments sont séparés par des <emphasis>métacaractères</emphasis>.  Les alias sont remplacés par leur équivalent.</para></listitem>
<listitem><para>Le Shell <emphasis>parses</emphasis> (analyse et transforme) les éléments en commandes simples ou composées.</para></listitem>
<listitem><para>Bash procède à diverses expansions d'éléments, les décomposant en listes de fichiers et commandes avec arguments.</para></listitem>
<listitem><para>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.</para></listitem>
<listitem><para>Les commandes sont exécutées.</para></listitem>
<listitem><para>Optionnellement le Shell attend que la commande s'achève pour récupérer son statut d'exécution.</para></listitem>
</itemizedlist>

</sect3>
<sect3 id="sect_01_04_01_02"><title>Les commandes Shell</title>
<para>Une simple commande Shell telle que <command>touch <filename>file1</filename> <filename>file2</filename> <filename>file3</filename></command> consiste en la commande elle-même suivie par des  arguments<indexterm><primary>arguments</primary><secondary>to a command</secondary></indexterm>, séparés par des espaces.</para>
<para>Les commandes Shell plus complexes sont des compositions variées de commandes simples&nbsp;: 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&nbsp;:</para>
<cmdsynopsis><command>ls | more</command></cmdsynopsis>
<cmdsynopsis><command>gunzip <filename>file.tar.gz</filename> | tar <option>xvf</option> <parameter>-</parameter></command></cmdsynopsis>

</sect3>
<sect3 id="sect_01_04_01_03"><title>La fonction Shell</title>
<para>Les fonctions Shell<indexterm><primary>functions</primary><secondary>execution</secondary></indexterm> sont un moyen de grouper des commandes pour une exécution ultérieure par l'appel d'un nom pour le groupe.  Elles sont exécutées tout comme des commandes <quote>régulières</quote>.  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.</para>
<para>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.</para>
<para>Les fonctions sont expliquées au <xref linkend="chap_11" />.</para>
</sect3>
<sect3 id="sect_01_04_01_04"><title>Les paramètres Shell</title>
<para>Un paramètre<indexterm><primary>shell</primary><secondary>parameters</secondary></indexterm> 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<indexterm><primary>variables</primary><secondary>definition</secondary></indexterm> est un paramètre qui mémorise un nom.  Une variable a une valeur et zéro ou plus attributs.  Les variables sont créées avec l'intégrée  <command>declare<indexterm><primary>built-ins</primary><secondary>declare</secondary></indexterm></command>.</para>
<para>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 <command>unset</command>.</para>
<para>L'assignation de variables est traitée à la <xref linkend="sect_03_02" />, l'utilisation poussée de variables au <xref linkend="chap_10" />.</para>
</sect3>
<sect3 id="sect_01_04_01_05"><title>Le processus d'expansion de Shell</title>
<para>L'expansion par le Shell<indexterm><primary>shell</primary><secondary>expansion</secondary></indexterm> est effectuée après que chaque ligne de commande ait été découpée en jetons ou morceaux.  Voici les opérations d'expansion&nbsp;:</para>
<itemizedlist>
<listitem><para>L'expansion d'accolades</para></listitem>
<listitem><para>L'expansion du tilde</para></listitem>
<listitem><para>L'expansion de paramètres et de variables</para></listitem>
<listitem><para>La substitution de commande</para></listitem>
<listitem><para>L'expansion arithmétique</para></listitem>
<listitem><para>Le découpage de mots</para></listitem>
<listitem><para>L'expansion de nom de fichiers</para></listitem>
</itemizedlist>
<para>Nous traiterons ces types d'expansion à la <xref linkend="sect_03_04" />.</para>
</sect3>
<sect3 id="sect_01_04_01_06"><title>Redirections</title>
<para>Avant qu'une commande soit exécutée, ses flux d'entrée et de sortie peuvent être redirigés<indexterm><primary>shell</primary><secondary>redirections</secondary></indexterm> en employant un symbole spécial interprété par le Shell.  La redirection peut aussi être employée pour ouvrir et fermer des fichiers dans l'environnement d'exécution du Shell.</para>

</sect3>
<sect3 id="sect_01_04_01_07"><title>L'exécution de commandes</title>
<para>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 mots qui ne sont pas des assignations de variables ou des redirections sont analysés&nbsp;; le premier mot restant après cette analyse est considéré comme étant le nom de la commande et le reste ses arguments<indexterm><primary>arguments</primary><secondary>definition</secondary></indexterm>.  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.</para>
<para>Une part importante du travail du Shell est de localiser<indexterm><primary>commands</primary><secondary>search for commands</secondary></indexterm> les commandes.  Bash le fait de cette façon&nbsp;:</para>
<itemizedlist>
<listitem><para>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é.</para></listitem>
<listitem><para>Si la commande n'est pas une fonction, la chercher dans la liste des intégrées.</para></listitem>
<listitem><para>Si la commande n'est ni une fonction ni une intégrée, la chercher dans les répertoires listés dans <varname>PATH<indexterm><primary>variables</primary><secondary>PATH</secondary></indexterm></varname>.  Bash se sert d'une <emphasis>table de hachage</emphasis> (zone de stockage en mémoire) pour récupérer le chemin complet des exécutables de sorte qu'une recherche extensive est évitée.</para></listitem>
<listitem><para>Si la recherche est un échec, Bash affiche un message d'erreur et retourne le statut d'exécution 127.</para></listitem>
<listitem><para>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.</para></listitem>
<listitem><para>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.</para></listitem>
<listitem><para>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.</para></listitem>
</itemizedlist>

</sect3>
<sect3 id="sect_01_04_01_08"><title>Les scripts Shell</title>
<para>Quand un fichier contenant<indexterm><primary>features</primary><secondary>scripts</secondary></indexterm> des commandes Shell est utilisé comme le premier argument n'étant pas une option à l'invocation de Bash (sans l'option <option>-c</option> ou l'option <option>-s</option>) 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 <varname>PATH</varname> si le fichier ne peut pas y être trouvé.</para>
</sect3>

</sect2>

</sect1>

<sect1 id="sect_01_05"><title>Ecrire de bons scripts</title>
<sect2 id="sect_01_05_01"><title>Caractéristiques d'un bon script</title>
        <para>Ce guide traite principalement du dernier bloc de construction Shell&nbsp;: les scripts. Quelques considerations générales<indexterm><primary>scripts</primary><secondary>considerations</secondary></indexterm> avant de continuer&nbsp;:</para>
<orderedlist>
<listitem><para>Un script devrait s'exécuter sans erreurs.</para></listitem>
<listitem><para>Il devrait accomplir la tâche pour laquelle il a été conçu.</para></listitem>
<listitem><para>La logique du programme est clairement définie et apparente.</para></listitem>
<listitem><para>Un script n'exécute pas des instructions inutiles.</para></listitem>
<listitem><para>Les scripts devraient être réutilisables.</para></listitem>

</orderedlist>
</sect2>
<sect2 id="sect_01_05_02"><title>Structure</title>
<para>La structure<indexterm><primary>scripts</primary><secondary>structure</secondary></indexterm> d'un script est très flexible.  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.</para>
<para>Au moment d'écrire un nouveau script, posez-vous les questions suivantes&nbsp;:</para>
<itemizedlist>
<listitem><para>Aurai-je besoin d'informations de la part de l'utilisateur ou de son environnement&nbsp;?</para></listitem>
<listitem><para>Comment vais-je mémoriser ces données&nbsp;?</para></listitem>
<listitem><para>Des fichiers doivent-ils être créés&nbsp;?  Où et avec quel propriétaire et quelles permissions&nbsp;?</para></listitem>
<listitem><para>Quelles commandes utiliserais-je&nbsp;?  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&nbsp;?</para></listitem>
<listitem><para>L'utilisateur a-t-il besoin que le script lui renvoie des informations&nbsp;?  Quand et pourquoi&nbsp;?</para></listitem>
</itemizedlist>
</sect2>
<sect2 id="sect_01_05_03"><title>Terminologie</title>
<para>La table ci-dessous donne un aperçu des termes de programmation<indexterm><primary>scripts</primary><secondary>terminology</secondary></indexterm> avec lesquels vous devez vous familiariser&nbsp;:</para>

<table id="table_01_01" frame="all">
<title>Vue générale des termes de programmation</title>
<tgroup cols="2" align="left" colsep="1" rowsep="1">
<thead>
<row><entry>Termes</entry><entry>Qu'est-ce que c'est&nbsp;?</entry></row>
</thead>
<tbody>
<row><entry>Contrôle de commande</entry><entry>Test du statut d'exécution (NdT&nbsp;: code retour) d'une commande pour déterminer si une portion du code doit être exécutée ou pas.</entry></row>
<row><entry>Branchement conditionnel</entry><entry>Une instruction logique du programme qui détermine quelle alternative du programme exécuter ensuite.</entry></row>
<row><entry>Enchaînement logique</entry><entry>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é.</entry></row>
<row><entry>Boucle</entry><entry>Partie de code qui s'exécute zéro fois ou plus.</entry></row>
<row><entry>Saisie de l'utilisateur</entry><entry>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.</entry></row>
</tbody>
</tgroup>
</table>

</sect2>
<sect2 id="sect_01_05_04"><title>Un mot sur l'ordre et la logique</title>
<para>Afin d'accélérer les phases de développement<indexterm><primary>scripts</primary><secondary>logic</secondary></indexterm>, l'ordre logique du programme devrait être pensé à l'avance.  C'est votre première étape quand vous développez un script.</para>
<para>Diverses méthodes peuvent être utilisées&nbsp;; 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.</para>
<para>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.</para>
<para>L'exemple<indexterm><primary>scripts</primary><secondary>logic flow example</secondary></indexterm> 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.</para>
<orderedlist>
<listitem><para>Voulez-vous paramétrer la rotation de journaux&nbsp;?</para>
        <orderedlist>
        <listitem><para>Si oui&nbsp;:</para>
                <orderedlist>
                <listitem><para>Indiquez le répertoire contenant les journaux sur lesquels la rotation se fera.</para></listitem>
                <listitem><para>Entrez le nom générique du fichier journal.</para></listitem>
                <listitem><para>Entrez le nombre de jours durant lesquels le journal doit être conservé.</para></listitem>
                <listitem><para>Enregistrer le paramétrage dans le fichier utilisateur 'crontab'.</para></listitem>

                </orderedlist></listitem>
        <listitem><para>Si non, aller à l'étape 3.</para></listitem>
        </orderedlist></listitem>
<listitem><para>Voulez-vous paramétrer la rotation d'un autre ensemble de journaux&nbsp;?</para>
        <orderedlist>
        <listitem><para>Si oui&nbsp;: répéter étape 1.</para></listitem>
        <listitem><para>Si non, aller à l'étape 3.</para></listitem>
        </orderedlist></listitem>
<listitem><para>Fin</para></listitem>
</orderedlist>
<para>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é.</para>

</sect2>

<sect2 id="sect_01_05_05"><title>Un exemple<indexterm><primary>scripts</primary><secondary>example</secondary></indexterm> Bash script&nbsp;: mysystem.sh</title>
<para>Le script <filename>mysystem.sh</filename> ci-dessous exécute des commandes bien connues  (<command>date</command>, <command>w</command>, <command>uname</command>, <command>uptime</command>) pour afficher des informations au sujet de la machine et sur vous.</para>
<screen>
<prompt>tom:~&gt;</prompt> <command>cat <option>-n</option> <filename>mysystem.sh</filename></command>
     1  #!/bin/bash
     2  clear
     3  echo "This is information provided by 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&nbsp;:"
    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&nbsp;:"
    19  uptime
    20  echo
    21
    22  echo "C'est pas plus compliqué&nbsp;!"
</screen>
<para>Un script commence toujours par ces 2 caractères&nbsp;: <quote>#!</quote>.  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 <command>w</command>&nbsp;; 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.</para>
<para><command>echo</command> et <command>printf</command> 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.</para>
<para>Voici le même script avec l'intégrée <command>printf</command>&nbsp;:</para>  
<screen>
<prompt>tom:~&gt;</prompt> <command>cat <filename>mysystem.sh</filename></command>
#!/bin/bash
clear
printf "This is information provided by 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&nbsp;:\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&nbsp;:\n"
uptime
printf "\n"

printf "C'est pas plus compliqué\n"
</screen>

<para>L'écriture d'un script convivial en insérant des messages est traité au <xref linkend="chap_08" />.</para>
<note><title>La localisation standard du Bourne Again Shell</title>
<para>Ceci implique que le programme <command>bash</command> est installé dans <filename>/bin</filename>.</para></note>
<warning><title>Si stdout n'est pas disponible</title>
<para>Si vous exécutez un script par cron, 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.</para></warning>
<para>Les chapitres suivants traiteront en détail les scripts ci-dessus.</para>

</sect2>

<sect2 id="sect_01_05_06"><title>Exemple&nbsp;: init script (NdT d'initialisation)</title>
<para>Un script init<indexterm><primary>scripts</primary><secondary>init scripts</secondary></indexterm> démarre les services système sur des machines 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, aussi appelés scripts de démarrage, sont stockés dans un endroit particulier de votre système, tel que <filename>/etc/rc.d/init.d</filename> ou <filename>/etc/init.d</filename>.  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)&nbsp;; 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 par exemple 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.</para>
<para>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 <command>init</command>, 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 <command>init</command> et <filename>inittab</filename> avant de vous lancer dans les scripts d'initialisation.</para>
<para>Voici un exemple très simple qui joue un son au démarrage<indexterm><primary>scripts</primary><secondary>init script example</secondary></indexterm> et à l'arrêt de la machine&nbsp;:</para>
<screen>
#!/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 &gt; /dev/audio
  ;;
'stop')
  cat /usr/share/audio/oh_no_not_again.au &gt; /dev/audio
  ;;
esac
exit 0
</screen>
<para>L'instruction <command>case</command> souvent utilisée dans ce genre de script est décrite à la  <xref linkend="sect_07_02_05" />.</para>
</sect2>

</sect1>

<sect1 id="sect_01_06"><title>Résumé</title>
<para>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&nbsp;:</para>
<itemizedlist>
<listitem><para><filename>/etc/profile</filename></para></listitem>
<listitem><para><filename>~/.bash_profile</filename></para></listitem>
<listitem><para><filename>~/.bashrc</filename></para></listitem>
</itemizedlist>
<para>Bash agit différemment en mode interactif&nbsp;; il a un mode à la norme POSIX et un autre restreint.</para>
<para>Les commandes Shell peuvent être classées en 3 groupes&nbsp;: 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.</para>
<para>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.</para>

</sect1>

<sect1 id="sect_01_07"><title>Exercices</title>
<para>Ces exercices vont vous entraîner pour le prochain chapitre&nbsp;:</para>
<orderedlist>
<listitem><para>Où le programme <command>bash</command> est localisé sur le système&nbsp;?</para></listitem>
<listitem><para>Utilisez l'option <option>--version</option> pour déterminer quelle version tourne.</para></listitem>
<listitem><para>Quels fichiers de configuration du Shell sont lus quand vous vous faites authentifier par le système au moyen de l'interface graphique puis en ouvrant une fenêtre de console&nbsp;?</para></listitem>
<listitem><para>Les Shell suivants sont-ils interactifs&nbsp;?  Sont-ils des Shell d'authentification&nbsp;?</para>
<itemizedlist>
<listitem><para>Un Shell ouvert en cliquant dans l'arrière plan de votre bureau graphique sur l'icône  <quote>Terminal</quote> ou l'équivalent dans un menu.</para></listitem>
<listitem><para>Un Shell que vous obtenez après avoir lancé la commande <command>ssh <parameter>localhost</parameter></command>.</para></listitem>
<listitem><para>Un Shell que vous activez en vous connectant à la console en mode texte.</para></listitem>
<listitem><para>Un Shell activé par la commande <command>xterm &amp;</command>.</para></listitem>
<listitem><para>Un Shell activé par le script <command>mysystem.sh</command>.</para></listitem>
<listitem><para>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.</para></listitem>
</itemizedlist>
</listitem>
<listitem><para>Pouvez-vous expliquer pourquoi <command>bash</command> ne quitte pas quand vous frapper les touches <keycap>Ctrl</keycap>+<keycap>C</keycap> sur la ligne de commande&nbsp;?</para></listitem>
<listitem><para>Afficher le contenu de la pile des répertoires.</para></listitem>
<listitem><para>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 à <filename>~/.bashrc</filename>&nbsp;:</para>
<cmdsynopsis><command>export <varname>PS1</varname>="<parameter>\u@\h \w&gt; </parameter>"</command></cmdsynopsis>
</listitem>
<listitem><para>Affichez les commandes mémorisées dans la table 'hash' de votre session de Shell en cours.</para></listitem>
<listitem><para>Combien de processus sont en train de tourner sur votre système&nbsp;?  Utilisez <command>ps</command> et <command>wc</command>, la première ligne de résultat de  <command>ps</command> n'est pas un processus&nbsp;!</para></listitem>
<listitem><para>Comment afficher le nom du système&nbsp;?  Seulement le nom, rien de plus&nbsp;!</para>
</listitem>
</orderedlist>

</sect1>
</chapter>