<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"/usr/local/share/xml/docbook/4.2/docbookx.dtd" [
<!ENTITY ccdil "&ccedil;">
<!ENTITY organ "N&#233;otech III">
<!ENTITY unix "<productname>Unix</productname>">
<!ENTITY Unix "<emphasis>Unix</emphasis>">
<!ENTITY bsd "<emphasis>BSD</emphasis>">
<!ENTITY ie "<abbrev>i.e.</abbrev>">
<!ENTITY cf "<abbrev>c.f.</abbrev>">
<!ENTITY shell "<foreignphrase>shell</foreignphrase>">
<!ENTITY todo "<command>--- T O  D O :</command>">
<!ENTITY fshell "<emphasis>csh</emphasis>">
<!ENTITY fshell2 "<emphasis>tcsh</emphasis>">
<!ENTITY _aut_Pre "<firstname>Pascal</firstname>">
<!ENTITY _aut_Nom "<surname>Picard</surname>">
<!ENTITY _aut_eMail "<email>pascal@seth.homeunix.net</email>">
<!ENTITY _aut_Init "<authorinitials>P.P.</authorinitials>">
<!ENTITY _affiliat "<affiliation><orgname>Corto E.T.F., K&amp;M</orgname><address>Sainte-Clotilde, Ile de la R&#233;union</address></affiliation>">
<!ENTITY _holder "<holder>Pascal PICARD, <emphasis>pascal@seth.homeunix.net</emphasis></holder>">
]>
<article class="techreport" lang="fr" revisionflag="changed">
  <articleinfo>
    <releaseinfo>$Id: C-csh_n_tcsh.xml,v 1.1.1.1 2006/04/02 16:27:31 Ivan Exp
    $</releaseinfo>

    <authorinitials>P.P.</authorinitials>

    <author>
      <firstname>Pascal</firstname>

      <surname>Picard</surname>

      <affiliation>
        <orgname>Corto E.T.F., K&amp;M</orgname>

        <address>Sainte-Clotilde, Ile de la Réunion</address>
      </affiliation>
    </author>

    <authorinitials>I.K.</authorinitials>

    <author>
      <firstname>Ivan</firstname>

      <surname>Kurzweg</surname>

      <affiliation>
        <orgname>Fremens Inst.</orgname>

        <address>La Possession, Ile de la Réunion</address>
      </affiliation>
    </author>

    <date>Last Updated: $Date: 2006/04/02 16:27:31 $</date>

    <title>Csh &amp; TCsh</title>

    <copyright>
      <year>2002-2006</year>

      <holder>Pascal PICARD, Ivan KURZWEG <emphasis>pascal@seth.homeunix.net,
      ik-r@wanadoo.fr</emphasis></holder>
    </copyright>

    <legalnotice>
      <para>Permission to use, copy, modify, and distribute this documentation
      for any purpose with or without fee is here by granted, provided that
      the above copyright notice and this permission notice appear in all
      copies.</para>

      <para>THE DOCUMENTATION IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
      WARRANTIES WITH REGARD TO THIS DOCUMENTATION INCLUDING ALL IMPLIED
      WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
      BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
      ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
      WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
      ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
      DOCUMENTATION.</para>
    </legalnotice>

    <keywordset>
      <keyword>interprète de commande, shell, csh, tcsh, completion,
      historique</keyword>
    </keywordset>
  </articleinfo>

  <abstract>
    <para>Le <foreignphrase>shell</foreignphrase> est d'abord l'interpréteur
    de commande d'un système <productname>Unix</productname> mais c'est aussi
    un quasi langage de programmation interpreté autorisant la
    récursivité.</para>

    <para>Historiquement le premier <foreignphrase>shell</foreignphrase> du
    système <productname>Unix</productname> est le
    <application>Bourne-Shell</application> (<command>sh</command>). Ce
    <foreignphrase>shell</foreignphrase> n'a cessé d'être amélioré et
    l'université de Berkeley qui a beaucoup contribué à la branche
    <emphasis><abbrev>BSD</abbrev></emphasis>
    d'<productname>Unix</productname> a développé le
    <application>C-Shell</application>
    (<command><emphasis>csh</emphasis></command>), un successeur de
    <command>sh</command> munit de fonctionnalités étendues par rapport à son
    ancêtre. Le <application>C-Shell</application> à son tour possède un
    successeur : <application>TC-Shell</application>
    (<command>tcsh</command>), ce dernier étend les fonctionnalités de son
    prédécesseur et apporte davantage de convivialité. Ces caractéristiques en
    font un équivalent au <application>GNU Bourne-Again-Shell</application>
    (<command>GNU/bash</command>).</para>

    <para>Ces <foreignphrase>shells</foreignphrase> syntaxiquement orientés
    <command>C</command> restent les shells par défaut des
    <foreignphrase>flavors</foreignphrase> <abbrev>BSD</abbrev> et c'est
    pourquoi nous nous proposons, dans ce support, de les présenter
    principalement dans un contexte d'interactivité où ils sont plutôt
    efficaces.</para>

    <para>Pour nous joindre : <email>pascal@seth.homeunix.net</email>
    <email>ik-r@wanadoo.fr</email></para>
  </abstract>

  <sect1>
    <title>Principes de fonctionnement de
    <command><emphasis>csh</emphasis></command></title>

    <sect2>
      <title>Rôle d'un <foreignphrase>shell</foreignphrase></title>

      <para>Le <foreignphrase>shell</foreignphrase> est un interpréteur de
      commande en ligne. Chaque entrée sur un terminal est analysée et
      décomposée en terme d'instructions à exécuter. Ces instructions peuvent
      impliquer des commandes internes que le
      <foreignphrase>shell</foreignphrase> connaît et est en mesure d'exécuter
      directement, ou bien d'autres commandes déclenchant des programmes que
      le <foreignphrase>shell</foreignphrase> va tenter de localiser et de
      lancer. Le <foreignphrase>shell</foreignphrase> dispose d'instructions
      (structures de contrôle, ...) et de variables qui le rende en partie
      comparable à un langage de programmation, de sorte que l'on peut écrire
      des <foreignphrase>shell scripts</foreignphrase>, littérallement de
      petits ou moyens programmes rédigé en
      <foreignphrase>shell</foreignphrase>.</para>

      <para>Un interpréteur <foreignphrase>shell</foreignphrase> exécutent
      trois types de commandes :</para>

      <orderedlist numeration="lowerroman" spacing="normal">
        <listitem>
          <para>Les <emphasis>commandes internes</emphasis>
          [<foreignphrase>built-in commands</foreignphrase>], comme par
          exemple : <command>cd</command>, <command>pwd</command>,
          <command>umask</command> ... ou bien encore les éléments
          algorithmiques tels <command>if .. then .. else .. endif</command>,
          <command>foreach ...</command> ...</para>
        </listitem>

        <listitem>
          <para>Les <emphasis>commandes externes</emphasis> indépendantes du
          <foreignphrase>shell</foreignphrase> et localisées dans les
          répertoires, comme par exemple : <command>ls</command>
          (<filename>/bin/ls</filename>), <command>find</command>
          (<filename>/usr/bin/find</filename>) ... Ces commandes nécessitent
          la création d'un nouveau <foreignphrase>shell</foreignphrase> pour
          leur exécution contrairement à celles relevant de la première
          catégorie.</para>
        </listitem>

        <listitem>
          <para>Les commandes définies par un <command>alias</command>.</para>
        </listitem>
      </orderedlist>
    </sect2>

    <sect2>
      <title>Caractéristiques de
      <command><emphasis>csh</emphasis></command></title>

      <para><itemizedlist>
          <listitem>
            <para>il possède un mécanisme d'historisation et de rappel (et
            d'éditions des commandes <emphasis>tcsh</emphasis>) ;</para>
          </listitem>

          <listitem>
            <para>il permet le contrôle des processus (suspension), reprise
            asynchrone (<foreignphrase>background</foreignphrase>) ou
            interactive (<foreignphrase>foreground</foreignphrase>)) ;</para>
          </listitem>

          <listitem>
            <para>il permet de traiter les tableaux de caractères ;</para>
          </listitem>

          <listitem>
            <para>il possède des directives de programmation proche du C
            ;</para>
          </listitem>

          <listitem>
            <para>il possède un mécanisme de
            <foreignphrase>completion</foreignphrase> ;</para>
          </listitem>

          <listitem>
            <para>il permet le calcul arithmétique.</para>
          </listitem>
        </itemizedlist></para>
    </sect2>

    <sect2>
      <title>Fichiers de configuration de
      <command><emphasis>csh</emphasis></command></title>

      <para>Lors du <foreignphrase>login</foreignphrase>,
      <command><emphasis>csh</emphasis></command> exécute les instructions
      contenues dans le fichier <filename>/etc/csh.cshrc</filename> puis
      celles du fichier <filename>/etc/csh.login</filename> puis celles de
      <filename>~/.cshrc</filename> (<command>tcsh</command> lit le script
      <filename>~/.tcshrc</filename>, s'il existe et sinon
      <filename>~/.cshrc</filename>) et enfin celles de
      <filename>~/.login</filename>. La signification du caractère
      <command>~</command> est donnée en <xref linkend="metacar" />. Lors de
      la fin de session (<foreignphrase>logout</foreignphrase>)
      <command><emphasis>csh</emphasis></command> ou <command>tcsh</command>
      exécutent les commandes des fichiers
      <filename>/etc/csh.logout</filename> et <filename>~/.logout</filename>,
      dans cet ordre.</para>

      <para>Un sous-<foreignphrase>shell</foreignphrase>, ne lit pas les
      fichiers suffixés en <filename>.login</filename> à son démarrage ni les
      fichiers suffixés en <filename>.logout</filename> à sa
      terminaison.</para>

      <para>De ce qui précède, on déduit que les commandes à exécuter une
      seule fois pendant une session sont à placer dans les fichiers suffixés
      en <filename>.login</filename> (typiquement les variables
      d'environnement), tandis que les autres sont à placer dans les fichiers
      suffixés en <filename>.cshrc</filename>.</para>

      <para>Le fichier <filename> ~/.cshrc</filename> contient typiquement :
      <itemizedlist>
          <listitem>
            <para>la définition des alias ;</para>
          </listitem>

          <listitem>
            <para>la définition des paramètres de fonctionnement ;</para>
          </listitem>

          <listitem>
            <para>l'initialisation des variables.</para>
          </listitem>
        </itemizedlist></para>

      <para><example>
          <title>fichier <filename> ~/.cshrc</filename></title>

          <programlisting width="80">

# ~/.cshrc
#
# $FreeBSD: src/share/skel/dot.cshrc,v 1.10.2.3 2001/08/01 17:15:46 obrien Exp $#
# .cshrc - csh resource script, read at beginning of execution by each shell
# see also csh(1), environ(7).
#

# Les alias
# -------------------------
alias j         jobs -l
alias la        /bin/ls -aoBG
alias lf        /bin/ls -FABG
alias ll        /bin/ls -loABG
alias gv        /usr/X11R6/bin/gv -color -safer -quiet \ 
-media a4 -portrait
alias rm        /bin/rm -i
alias wget      `which wget` -N -c -S
alias emacs     `which emacs` -q
alias gnuplot   `which gnuplot` -background ivory
alias xdvi      `which xdvi` -fg DarkSlateGray  -paper a4 
alias xfig      `which xfig` -center -centim -pap a4 -po
alias dvips     `which dvips` -t a4 -o out.ps
alias h         'history -r \!* | less'
alias psnup     `which psnup` -pa4 -2up -m0.5cm

# Paramètres et variables.
# -------------------------
limit coredumpsize 0  # prevent core files from being written to disc
# A righteous umask
umask 077
set prompt='%B%n%b@%m:%c &gt; '
set prompt2='%B%n%b:&gt;&gt; '
set path = (/usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin \
/usr/bin /usr/X11R6/bin $HOME/bin)
set correct = cmd

/usr/X11R6/bin/xrdb -load ~/.Xdefaults &gt;&amp; /dev/null

if ($?prompt) then
        # An interactive shell -- set some stuff up
        set filec
        set history = 2048
        set savehist = 2048
        set histfile = ~/.history
        set mail = (/var/mail/$USER)
        set notify      
        set addsuffix
        set autolist
        set machbeep = nomatch
        set cdpath = ( ~ ~/bin )
        set symlinks = ignore
        if ( $?tcsh ) then
                set echo_style = both
                set histdup = all
                set savehist = ( 2000 merge )
                bindkey "^W" backward-delete-word
                bindkey -k up history-search-backward
                bindkey -k down history-search-forward
                source ~/.tcsh_comp
        endif
endif

</programlisting>
        </example></para>

      <para>Le fichier <filename> ~/.login </filename> contient
      essentiellement la définition des variables d'environnement.</para>

      <para><example>
          <title>fichier <filename> ~/.login</filename></title>

          <programlisting width="80">

# ~/.login                                                                      

setenv LC_CTYPE fr_FR.ISO8859-15
setenv PAGER less
setenv MOZILLA_HOME /usr/X11R6/bin/mozilla
setenv MACHTYPE i386
setenv EDITOR emacs
setenv HOSTTYPE FreeBSD
setenv CPUTYPE k7
setenv OSTYPE FreeBSD
setenv TEXEDIT emacs
setenv VENDOR amd
setenv SHLVL 1
setenv LSCOLORS "ExFxbxcxBxdxHBhbafacad" 
setenv CLICOLOR 1
setenv CLICOLOR_FORCE 1

# COLORTERM to "rxvt"
setenv COLORTERM "rxvt"

# COLORFGBG to "default" 
setenv COLORFGBG "default" 

setenv RSYNC_RSH /usr/bin/ssh
setenv CVSROOT /home/cvsroot
setenv BLOCKSIZE       K
setenv TERM xterm-color

[ -x /usr/games/fortune ] &amp;&amp; /usr/games/fortune freebsd-tips

</programlisting>
        </example></para>

      <para>Le fichier <filename> ~/.logout </filename> contient
      essentiellement des commandes de suppression de fichiers
      inutiles.</para>

      <para><example>
          <title>fichier <filename> ~/.logout</filename></title>

          <programlisting width="80">

# ~/.logout                                                                     

echo -n "clean up before logout ..."
find $HOME \( -type f \
              \( -name a.out -o -name "*.bak" -o -name core  -o \
                 -name "#*#" -o -name "#.*#"  -o -name "*.o" -o \
                 -name "*~"  -o -name ".*~" \) -exec /bin/rm -f {} \; &gt; /dev/nul
l \)
echo "... done" 
echo "last connexion at [`date +%Y-%M-%d` a `date +%H:%I:%S`] pour [`logname`] s
ur [`tty`]" &gt; ~/.deconnex

</programlisting>
        </example></para>

      <qandaset defaultlabel="qanda">
        <qandaentry>
          <question>
            <para>Quel est le rôle de la commande <command>find</command> dans
            le contexte du listing précédent (<filename>~/.logout</filename>)
            ?</para>
          </question>

          <answer>
            <para></para>
          </answer>
        </qandaentry>
      </qandaset>

      <para>Il est possible à tout moment et notamment après une modification
      de réexécuter les fichiers au moyen de la commande
      <command>source</command>. <programlisting width="80">
$ &gt; source ~/.login                                                             
$ &gt; source ~/.cshrc
</programlisting> <warning>
          <para>Dans les distributions <emphasis>xBSD</emphasis> on peut voir
          les deux fichiers suivants : <filename>/.login</filename> et
          <filename>/.profile</filename> (situés à la racine). Ils sont
          exécutés uniquement dans le mode mono-utilisateur
          [<foreignphrase>single-user mode</foreignphrase>]. Leurs
          modifications sont à faire avec le plus grand soin.</para>
        </warning></para>
    </sect2>

    <sect2 id="envvar">
      <title>Variables prédéfinies et d'environnement</title>

      <para>On parle de <emphasis>variables d'environnement</emphasis> car
      elles sont <quote>automatiquement</quote> transmises à tous les
      processus fils du <foreignphrase>shell</foreignphrase>,
      <abbrev>i.e.</abbrev> tous les processus lancés par ce
      <foreignphrase>shell</foreignphrase>.</para>

      <para>Les variables qui suivent ont un sens particulier pour le
      <foreignphrase>shell</foreignphrase> (<emphasis>csh</emphasis> et
      <emphasis>tcsh</emphasis>), elles sont utilisées par certaines commandes
      du <foreignphrase>shell</foreignphrase> ou du système. Parmi elles,
      <varname>argv</varname>, <varname>cwd</varname>,
      <varname>home</varname>, <varname>path</varname>,
      <varname>prompt</varname>, <varname>shell</varname> et
      <varname>status</varname> sont toujours définies par le
      <foreignphrase>shell</foreignphrase>. Si l'on exclut les variables
      <varname>cwd</varname> et <varname>status</varname>, leur positionnement
      intervient seulement à l'initialisation. Ces variables ne sont plus
      modifiées, sauf éventuellement par l'utilisateur.</para>

      <para><table>
          <!-- orient='land' pgwide='0'> -->

          <title>Variables d'environnement</title>

          <!-- one of (graphic mediaobject tgroup) -->

          <tgroup align="left" cols="2">
            <colspec colname="c1" colnum="1" colwidth="1*+1" />

            <colspec colname="c2" colnum="2" colwidth="3*+1" />

            <thead valign="middle">
              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="center">Variable d'environnement</entry>

                <entry align="center">Sémantique</entry>
              </row>
            </thead>

            <tbody valign="middle">
              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>argv</varname></entry>

                <entry>Arguments du <foreignphrase>shell</foreignphrase>,
                résultant de la substitution des paramètres positionnels.
                <varname>$argv[1]</varname> correspond à
                <varname>$1</varname>, <varname>$argv[2]</varname> à
                <varname>$2</varname> ...</entry>
              </row>

              <row>
                <entry align="left"><varname>autologout</varname></entry>

                <entry>[<emphasis
                role="bold"><emphasis>tcsh</emphasis></emphasis>] Positionné à
                un certain nombre de minutes, permet de déconnecter
                automatiquement l'utilisateur au bout de cette période
                d'inactivité.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>cdpath</varname></entry>

                <entry>Liste de répertoires alternatifs dans lesquels sera
                effectuée la recherche des sous-répertoires lors de
                l'utilisation de la commande <command>cd</command> avec un
                argument de type nom relatif.</entry>
              </row>

              <row>
                <entry align="left"><varname>correct</varname></entry>

                <entry>[<emphasis
                role="bold"><emphasis>tcsh</emphasis></emphasis>]
                Positionnable à <emphasis>all</emphasis> ou
                <emphasis>cmd</emphasis>. Dans le deuxième cas, permet la
                correction des erreurs de typos sur les noms de
                commandes.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>cwd</varname></entry>

                <entry>Chemin absolu du répertoire courant.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>echo</varname></entry>

                <entry></entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>filec</varname></entry>

                <entry>Permet la <foreignphrase>completion</foreignphrase> des
                noms de fichiers.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>histchars</varname></entry>

                <entry>Chaîne de caractères à utiliser dans les substitutions
                de l'historique. Les éléments de cette chaîne remplacent les
                caractères standards, ainsi le premier caractère de cette
                chaîne remplace le '<command>!</command>', le second remplace
                le '<command>^</command>' ...</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>histfile</varname></entry>

                <entry>Chemin d'accès au fichier d'historique.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>history</varname></entry>

                <entry>Permet de contrôler le nombre de lignes de
                l'historique. Noter que la dernière commande exécutée est
                toujours sauvegardée dans l'historique.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>home</varname></entry>

                <entry>Désigne le répertoire de localisation de celui qui
                invoque la commande. L'expansion de nom de fichier
                <command>~</command> se réfère à cette variable.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>ignoreeof</varname></entry>

                <entry>Le positionnement de cette variable permet au
                <foreignphrase>shell</foreignphrase> d'ignorer le caractère de
                fin de fichier quand il est généré depuis un terminal. Cela
                permet donc d'immuniser le
                <foreignphrase>shell</foreignphrase> d'une fin accidentelle
                déclenchée par la séquence <command>^D</command> (lire
                <command>&lt;CTRL&gt;-D</command>).</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>inputmode</varname></entry>

                <entry>[<emphasis
                role="bold"><emphasis>tcsh</emphasis></emphasis>] Définit le
                mode en insertion (par défaut) ou en
                <foreignphrase>overwrite</foreignphrase> pour l'édition de la
                ligne de commande .</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>mail</varname></entry>

                <entry>Indique le fichier dans lequel le
                <foreignphrase>shell</foreignphrase> contrôle l'arrivée de
                nouveaux messages. Si la première valeur spécifiée dans
                <varname>mail</varname> est numérique, elle surcharge
                l'intervalle de temps entre chaque vérification, fixé par
                défaut à 10 minutes. Si la variable spécifie différents
                fichiers, chacun d'eux sera scruté pour détecter l'arrivée de
                nouveaux messages.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>noclobber</varname></entry>

                <entry>Modifie la sémantique des commandes de redirections
                <command>&gt;</command> et <command>&gt;&gt;</command>
                permettant ainsi d'éviter un effacement accidentel.
                L'utilisation de <command>&gt;</command> renvoit une erreur si
                le fichier existe. Quand à <command>&gt;&gt;</command>, elle
                se réfère uniquement aux fichiers existants.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>noglob</varname></entry>

                <entry>Si cette variable est positionnée, elle inhibe la
                fonctionnalité d'expansion des noms de fichiers. Surtout utile
                dans les scripts <foreignphrase>shell</foreignphrase>.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>nonomatch</varname></entry>

                <entry>Si cette variable est positionnée, il n'y a pas
                d'erreurs lorsque le mécanisme d'expansion des noms de
                fichiers ne correspond pas à tous les fichiers existants. Dans
                ce cas le motif est retourné.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>notify</varname></entry>

                <entry>Si positionné alors permet au
                <foreignphrase>shell</foreignphrase> de notifier de manière
                asynchrone la <foreignphrase>completion</foreignphrase> des
                <foreignphrase>jobs</foreignphrase>. Le comportement par
                défaut spécifie de présenter la
                <foreignphrase>completion</foreignphrase> des
                <foreignphrase>jobs</foreignphrase> avant d'imprimer le
                <foreignphrase>prompt</foreignphrase>.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>path</varname></entry>

                <entry>Définit l'ensemble des chemins dans lesquels le
                <foreignphrase>shell</foreignphrase> recherche les commandes
                externes à exécuter.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>prompt</varname></entry>

                <entry>Définit l'invite de commandes en mode
                interactif.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>rmstar</varname></entry>

                <entry>[<emphasis
                role="bold"><emphasis>tcsh</emphasis></emphasis>] Si
                positionné, permet de demander à l'utilisateur confirmation
                lorsqu'il tape la commande <computeroutput>rm
                *</computeroutput>.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>savehist</varname></entry>

                <entry>Si l'argument est numérique, spécifie le nombre de
                lignes sauvegardées dans <filename>~/.history</filename>,
                quand l'utilisateur se déloggue.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>shell</varname></entry>

                <entry>Fichier dans lequel réside le
                <foreignphrase>shell</foreignphrase>.</entry>
              </row>

              <row>
                <entry align="left"><varname>shlvl</varname></entry>

                <entry>[<emphasis
                role="bold"><emphasis>tcsh</emphasis></emphasis>] Nombre de
                <foreignphrase>shell</foreignphrase> empilés, remis à 1 par un
                <foreignphrase>shell</foreignphrase> de
                <foreignphrase>login</foreignphrase>.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>status</varname></entry>

                <entry>Statut retourné par la dernière commande
                exécutée.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>time</varname></entry>

                <entry>Si cette variable est positionnée (valeur en secondes),
                alors toute commande dont la durée d'exécution dépasse cette
                valeur est suivie à sa terminaison de l'affichage de
                statistiques sur les temps utilisateur, système et réel
                consommés ainsi que le ratio temps utilisateur et temps
                système sur temps réel consommé.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="left"><varname>verbose</varname></entry>

                <entry></entry>
              </row>
            </tbody>
          </tgroup>
        </table></para>

      <formalpara>
        <title>Relations entre variables du
        <foreignphrase>shell</foreignphrase> et les variables
        d'environnement</title>

        <para>En <emphasis>csh</emphasis> comme en <emphasis>tcsh</emphasis>
        certaines variables du <foreignphrase>shell</foreignphrase> et des
        variables d'environnement sont maintenues à des valeurs identiques par
        le <foreignphrase>shell</foreignphrase>. Ce sont les variables
        <varname>user</varname> et <varname>USER</varname>,
        <varname>group</varname> et <varname>GROUP</varname>,
        <varname>home</varname> et <varname>HOME</varname>,
        <varname>term</varname> et <varname>TERM</varname>,
        <varname>path</varname> et <varname>PATH</varname>, et enfin
        <varname>shlvl</varname> et <varname>SHLVL</varname>.</para>
      </formalpara>
    </sect2>

    <sect2 id="metacar">
      <title>Métacaractères et autres caractères spéciaux du
      <foreignphrase>shell</foreignphrase></title>

      <para>Les métacaractères jouent le rôle de classe de représentation des
      fichiers dans le contexte du répertoire courant si rien n'est précisé ou
      bien dans celui du répertoire explicitement nommé.</para>

      <itemizedlist>
        <listitem>
          <para>Le caractère <command>~</command> placé en première position
          désigne le répertoire personnel de l'utilisateur courant :</para>

          <informalexample>
            <para><programlisting width="80">

$ echo ~                                                                        
/home/.sysop

$ ls -l ~/elemntBase
total 3
drwx------  6 sysop  gnu  512 Mar 14 14:43 Part1
drwx------  4 sysop  gnu  512 Mar 28 16:06 Part2
drwx------  3 sysop  gnu  512 Mar 20 22:20 Synthese

</programlisting></para>
          </informalexample>
        </listitem>

        <listitem>
          <para>Le caractère <command>*</command> est substituable par
          n'importe quelle combinaison de 0 ou plusieurs caractères.</para>

          <para>Exemple : Lister l'ensemble des fichiers commençant par le
          motif <filename>C-csh_n_tcsh</filename> du répertoire courant
          :</para>

          <para><programlisting width="80">

$ ls xb*                                                              
xba  xbc xbd xbe xbg xbf xbg xbh             

</programlisting></para>

          <informalexample>
            <para>Exemple : Lister les fichiers (non <quote>cachés</quote>) du
            répertoires courant :</para>

            <para><programlisting width="80">
$ &gt; <command>echo *</command>
xaa xab xac xad xae xaf xagxba  xbc xbd xbe xbg xbf xbg xbh xaa xab xac xad xae xaf xag
</programlisting></para>
          </informalexample>

          <warning>
            <para>Les fichiers commençant par le caractère
            <command>.</command> ou fichiers <quote>cachés</quote>
            d'<productname>Unix</productname> [<foreignphrase>dot
            files</foreignphrase>] ne peuvent être remplacés par aucun
            caractère, <abbrev>i.e.</abbrev> le caractère
            <quote><command>*</command></quote> est inopérant.</para>
          </warning>
        </listitem>

        <listitem>
          <para>Le caractère <command>?</command> est substituable par un
          unique caractère quelconque.</para>

          <informalexample>
            <para>Exemple : Lister les fichiers commençant par le motif
            <filename>C-csh_n_tcsh</filename> et dont le suffixe est réduit à
            deux caractères :</para>

            <programlisting width="80">

$ echo C-csh_n_tcsh.??                                                          
C-csh_n_tcsh.fo C-csh_n_tcsh.ps   
                                            
</programlisting>
          </informalexample>
        </listitem>

        <listitem>
          <para>Les caractères <command>[]</command> permettent une
          substitution par un caractère parmi l'ensemble dénoté par les
          crochets.</para>

          <informalexample>
            <para>Exemple : Lister les fichiers <quote>cachés</quote> du
            répertoire <filename>$HOME</filename> de l'utilisateur courant,
            dont le second caractère est compris entre 'a' et 'e' (le premier
            étant le <quote>.</quote>) :</para>

            <programlisting width="80">

$ ls -d ~/.[a-e]*                                                               
/home/pascal/.acrobat        /home/pascal/.cshrc          /home/pascal/.emacs.d
/home/pascal/.acrorc         /home/pascal/.cvsrc          /home/pascal/.esd
/home/pascal/.adobe          /home/pascal/.deconnex       /home/pascal/.esd_auth
/home/pascal/.autosave       /home/pascal/.dia            /home/pascal/.exit.log
/home/pascal/.bash_history   /home/pascal/.emacs

</programlisting>
          </informalexample>

          <informalexample>
            <para>Autre exemple, utilisation de la négation (extension
            <command>tcsh</command>) marqué par le caractère
            <command>^</command> : Lister les fichiers cachés du répertoire
            <filename>$HOME</filename> de l'utilisateur courant, dont le
            second caractère n'est ni '.', ni 'a', ni 'b', ni 'c', ni 'd' ni
            'e' (le premier étant un '.') :</para>

            <programlisting width="80">

$ ls -d ~/.[^.a-e]*                                                             
/home/pascal/.fetchmail.pid                /home/pascal/.profile.rc             
/home/pascal/.fetchmailrc                  /home/pascal/.ressources
/home/pascal/.fonts.cache-1                /home/pascal/.rhosts
/home/pascal/.fr                           /home/pascal/.shadow_todo
/home/pascal/.gkrellm                      /home/pascal/.shrc
/home/pascal/.gnupg                        /home/pascal/.sversionrc
/home/pascal/.gv                           /home/pascal/.tcsh_comp
/home/pascal/.history                      /home/pascal/.themeinstaller
/home/pascal/.ispell_francais              /home/pascal/.user60.rdb
/home/pascal/.login                        /home/pascal/.weblink
/home/pascal/.logout                       /home/pascal/.xemacs
/home/pascal/.mail_aliases                 /home/pascal/.xfigrc
/home/pascal/.mailcap                      /home/pascal/.xinitrc
/home/pascal/.mailrc                       /home/pascal/.xmms
/home/pascal/.mgprc                        /home/pascal/.xsession
/home/pascal/.mime.types                   /home/pascal/.xsession-errors
/home/pascal/.mozilla                      /home/pascal/.xwm.msgs
/home/pascal/.mutt

</programlisting>
          </informalexample>
        </listitem>

        <listitem>
          <para>Les caractères <command>{ }</command> permettent la
          substitution par un mot de l'énumération dénotée par les
          accolades.</para>

          <informalexample>
            <para>Exemple : Lister les fichiers se terminant par les suffixes
            .xml et .pdf et .fo :</para>

            <programlisting width="80">

$ ls C-csh_n_tcsh.{xml,pdf,fo}                                                  
C-csh_n_tcsh.fo  C-csh_n_tcsh.pdf C-csh_n_tcsh.xml                              

</programlisting>
          </informalexample>
        </listitem>

        <listitem>
          <para>Quelques autres caractères spéciaux</para>

          <table frame="all" orient="port">
            <title>Autres caractères spéciaux du
            <foreignphrase>shell</foreignphrase></title>

            <!-- one of (graphic mediaobject tgroup) -->

            <tgroup align="left" cols="2">
              <colspec colname="c1" colnum="1" colwidth="1*+1" />

              <colspec colname="c2" colnum="2" colwidth="3*+1" />

              <thead>
                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center">Caractère</entry>

                  <entry align="center">Sémantique</entry>
                </row>
              </thead>

              <tbody>
                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>;</command></entry>

                  <entry>Séparateur de commande, <abbrev>i.e.</abbrev>
                  opérateur de séquentialité.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>&amp;</command></entry>

                  <entry>Séparateur de commande qui place la commande qui le
                  précède en arrière-plan, <abbrev>i.e.</abbrev> en exécution
                  asynchrone.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>\</command></entry>

                  <entry>Quote le caractère qui le suit et notamment pour les
                  caractères spéciaux, inhibe leur sémantique
                  particulière.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>$</command></entry>

                  <entry>Accède au contenu de la variable.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>'</command></entry>

                  <entry>[<foreignphrase>quote</foreignphrase>] Quote le texte
                  qui le suit jusqu'au <command>'</command> fermant.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>`</command></entry>

                  <entry>[<foreignphrase>backquote</foreignphrase>] Considère
                  le texte quoté comme une commande et la remplace par le
                  résultat de son évaluation.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>"</command></entry>

                  <entry>[<foreignphrase>double quote</foreignphrase>] Quote
                  le texte qui le suit en interpolant les éventuelles
                  variables qu'il contient.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>!</command></entry>

                  <entry>Substitution dans l'historique.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>|</command></entry>

                  <entry>Tube [<foreignphrase>pipe</foreignphrase>].</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>&gt;</command> et
                  <command>&gt;&gt;</command></entry>

                  <entry>Redirection de la sortie standard.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>&lt;</command> et
                  <command>&lt;&lt;</command></entry>

                  <entry>Redirection de l'entrée standard.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>#</command></entry>

                  <entry>Marque le début d'un commentaire,
                  <abbrev>i.e.</abbrev> pas d'expansion.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>&amp;&amp;</command></entry>

                  <entry>Et [<foreignphrase>And</foreignphrase>]
                  logique.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center"><command>||</command></entry>

                  <entry>Ou [<foreignphrase>Or</foreignphrase>]
                  logique.</entry>
                </row>
              </tbody>
            </tgroup>
          </table>
        </listitem>
      </itemizedlist>
    </sect2>
  </sect1>

  <!-- 2e PARTIE -->

  <sect1>
    <title>Les commandes internes</title>

    <sect2>
      <title><command>source</command></title>

      <para>Cette commande exécute le fichier (et ces éventuels arguments) qui
      lui est passé en argument dans le <foreignphrase>shell</foreignphrase>
      courant (<abbrev>i.e.</abbrev> pas de <command>fork</command> et donc
      modification (éventuelle) du <foreignphrase>shell</foreignphrase>
      courant).</para>

      <para><programlisting width="80">

$ source ~/.login                                                               

</programlisting></para>
    </sect2>

    <sect2 id="setenv">
      <title><command>setenv/unsetenv</command></title>

      <para>La commande <command>setenv</command> permet d'initialiser une
      variable d'environnement, <abbrev>i.e.</abbrev> une variable qui sera
      transmise à tous les processus fils du
      <foreignphrase>shell</foreignphrase>.</para>

      <para><programlisting width="80">

setenv OSTYPE  FreeBSD                                                          
setenv CPUTYPE k7
setenv PAGER   less

</programlisting></para>

      <para>La commande <command>unsetenv</command> permet de supprimer une
      variable d'environnement.</para>
    </sect2>

    <sect2>
      <title><command>set/unset</command></title>

      <para>La commande <command>set</command> a deux fonctions :</para>

      <itemizedlist>
        <listitem>
          <para>l'initialisation d'une variable :</para>
        </listitem>
      </itemizedlist>

      <para><programlisting width="80">

$ set path=( $path ~/bin )                                                      

</programlisting> Cette déclaration permet d'enrichir la variable
      <command>path</command> du répertoire <command>bin</command> de
      l'utilisateur.</para>

      <itemizedlist>
        <listitem>
          <para>la déclaration d'une option :</para>
        </listitem>
      </itemizedlist>

      <para><programlisting format="linespecific" width="80">

$ set ignoreeof                                                                 

</programlisting> Cette option permet d'immuniser
      <command><emphasis>csh</emphasis></command> d'une destruction
      accidentelle. Il est normalement possible de clôre un terminal avec la
      séquence <command>^D</command> (lire <command>&lt;CTRL&gt;-D</command>),
      mais si on positionne l'option <command>ignoreeof</command> la séquence
      précédente n'a plus d'effet.</para>

      <para>La commande <command>unset</command> a évidement un effet
      symétrique. Elle permet donc de désarmer une option ou de supprimer une
      variable.</para>

      <important>
        <para>La portée de ces actions est limitée au
        <foreignphrase>shell</foreignphrase> courant contrairement à la
        commande précédente (<abbrev>c.f.</abbrev> <xref
        linkend="setenv" />).</para>
      </important>
    </sect2>

    <sect2>
      <title><command>alias</command>/<command>unalias</command></title>

      <para>Ce mécanisme permet de définir ou de redéfinir une commande.
      Exemple :</para>

      <para><programlisting width="80">

$ alias la /bin/ls -aoBG          # definition de l'alias la                    
$ alias rm /bin/rm -i             # definition de l'alias rm
$ alias                           # afficher les alias courants
la      (/bin/ls -aoBG)
rm      (/bin/rm -i)

</programlisting></para>

      <para>En général, on place ces <command>alias</command> dans le fichier
      <filename>~/.cshrc</filename>. Si on veut supprimer un
      <command>alias</command> on utilise la commande
      <command>unalias</command> comme suit :</para>

      <para><programlisting width="80">

$ unalias rm                                                                    
$ alias                                # afficher les alias courants
la      (/bin/ls -aoBG)

</programlisting></para>

      <para>Pour ré-accéder à la commande masquée par son alias, comme dans
      l'exemple précédent où nous avons surchargé la commande classique
      <command>rm</command>, il suffit de : <itemizedlist>
          <listitem>
            <para>Soit utiliser la commande par son nom absolu :
            <command>/bin/rm</command>.</para>
          </listitem>

          <listitem>
            <para>Soit faire précéder la commande du caractère
            <foreignphrase>backslash</foreignphrase> (\), on tape donc
            toujours dans le cadre de l'exemple précédent :
            <command>\rm</command></para>
          </listitem>
        </itemizedlist></para>

      <qandaset defaultlabel="qanda">
        <qandaentry>
          <question>
            <para>Que signifie la commande <command>rm -i</command> ?</para>
          </question>

          <answer>
            <para></para>
          </answer>
        </qandaentry>
      </qandaset>
    </sect2>

    <sect2>
      <title><command>umask</command></title>

      <para>Cette commande permet de spécifier (si elle est suivie d'un
      argument valide) ou d'afficher la valeur du masque de création des
      objets <abbrev>i.e.</abbrev> des fichiers.</para>

      <para><programlisting width="80">

$ umask  # affiche la valeur telle que prédéfinie dans ~/.cshrc                 
77       # autrement dir 0077   
$ umask 0027
$ umask
27       # autrement dit 0027

</programlisting></para>
    </sect2>

    <sect2>
      <title>Historique</title>

      <para>Ce mécanisme a pour rôle de mémoriser les <varname>n</varname>
      dernières commandes entrées, ce nombre étant un paramètre réglable. Cela
      permet de visualiser, d'éditer et/ou exécuter à nouveau les commandes
      mémorisées. La commande suivante permet d'activer l'historisation des
      commandes, elle signifie que les 512 dernières commandes seront
      mémorisées : <programlisting width="80">

$ set history = 512                                                             

</programlisting></para>

      <para>La commande suivante permet en plus de sauvegarder les
      <varname>m</varname> dernières commandes dans
      <filename>~/.history</filename> au <command>logout</command>. Il est
      évident que <varname>m</varname> est au plus égale à
      <varname>n</varname>. Ici, nous ne retenons que les 256 dernières
      commandes : <programlisting width="80">

$ set savehist = 256                                                            

</programlisting></para>

      <para>La commande <command>history</command> permet d'afficher les
      commandes dans l'ordre de leur mémorisation. <programlisting width="80"> 

$ history                                                                       
...
80  8:57    cp csh/Makefile Makefile.gen
81  9:03    more Makefile.gen
82  9:06    sed -e 's/SRCNAME=C-csh_n_tcsh/SRCNAME=/' Makefile.gen &gt; Makefile   
83  9:07    xemacs createinf.sh
84  9:09    which mkdir
85  9:09    rm -rf html/ &amp;&amp; make check &amp;&amp; make html
86  9:10    ls -l csh/
87  9:12    echo $$

</programlisting></para>

      <para>Pour relancer une commande, il suffit de l'appeler par son numéro
      (relativement à l'historique) en la préfixant par le caractère !. Par
      exemple, si on veut relancer la commande 84, il suffit de faire :
      <programlisting width="80">

$ !84                                                                           
which mkdir
/bin/mkdir

</programlisting></para>

      <para><table>
          <title>Quelques commandes de manipulation de l'historique</title>

          <!-- one of (graphic mediaobject tgroup) -->

          <tgroup align="left" cols="2">
            <colspec colname="c1" colnum="1" colwidth="1*+1" />

            <colspec colname="c2" colnum="2" colwidth="3*+1" />

            <thead>
              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="center">Expression</entry>

                <entry align="center">Sémantique</entry>
              </row>
            </thead>

            <tbody>
              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="center"><command>!!</command></entry>

                <entry>Répéter la dernière commande.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry
                align="center"><command>!</command><emphasis>n</emphasis></entry>

                <entry>Répéter la commande numéro
                <emphasis>n</emphasis>.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry
                align="center"><command>!-</command><emphasis>n</emphasis></entry>

                <entry>Répéter la
                <emphasis>n<superscript>ième</superscript></emphasis>
                précédent la dernière de l'historique, <abbrev>i.e.</abbrev>
                !-2 : avant dernière commande.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry
                align="center"><command>!</command><emphasis>texte</emphasis></entry>

                <entry>Répéter la dernière commande commençant par
                <emphasis>texte</emphasis>.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry
                align="center"><command>!?</command><emphasis>texte</emphasis></entry>

                <entry>Répéter la dernière commande contenant
                <emphasis>texte</emphasis>.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry
                align="center"><command>!:</command><emphasis>n</emphasis></entry>

                <entry>Répéter le
                <emphasis>n<superscript>ième</superscript></emphasis> mot de
                la dernière commande.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="center"><command>!$</command></entry>

                <entry>Répéter le dernier mot de la dernière commande.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="center"><command>!*</command></entry>

                <entry>Répéter tous les arguments de la dernière
                commande.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry
                align="center"><command>^</command><emphasis>old</emphasis><command>^</command><emphasis>new</emphasis></entry>

                <entry>Répéter la dernière commande en commençant par
                remplacer la première occurence de <emphasis>old</emphasis>
                par <emphasis>new</emphasis>.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry
                align="center"><command>!</command><emphasis>n</emphasis><command>:s^</command><emphasis>old</emphasis><command>^</command><emphasis>new</emphasis></entry>

                <entry>Répéter la
                <emphasis>n</emphasis><superscript>ième</superscript> commande
                en commençant par remplacer la première occurence de
                <emphasis>old</emphasis> par <emphasis>new</emphasis>.</entry>
              </row>

              <row>
                <!-- one of (entrytbl entry) -->

                <entry
                align="center"><command>!</command><emphasis>n</emphasis><command>:gs^</command><emphasis>old</emphasis><command>^</command><emphasis>new</emphasis></entry>

                <entry>Répéter la
                <emphasis>n</emphasis><superscript>ième</superscript> commande
                en commençant par remplacer toutes les occurences de
                <emphasis>old</emphasis> par <emphasis>new</emphasis>
                (substitution globale).</entry>
              </row>
            </tbody>
          </tgroup>
        </table></para>

      <para>Pour terminer, il peut être intéressant de positionner l'alias
      suivant dans son <filename>~/.cshrc</filename>. <programlisting
      width="80">

alias h         'history -r \!* | less'                                         

</programlisting></para>

      <qandaset defaultlabel="qanda">
        <qandaentry>
          <question>
            <para>Que signifie donc cet alias ?</para>
          </question>

          <answer>
            <para></para>
          </answer>
        </qandaentry>
      </qandaset>
    </sect2>

    <sect2>
      <title><foreignphrase>Completion</foreignphrase></title>

      <para>En <command><emphasis>csh</emphasis></command> la
      <foreignphrase>completion</foreignphrase> est activée par le
      positionnement de la variable d'environnement <command>filec</command>
      (<abbrev>c.f.</abbrev> <quote><xref linkend="envvar" /></quote>). Ce
      mécanisme permet, selon le contexte, de compléter les noms de fichiers
      ou d'utilisateurs à partir de la saisie d'un préfixe suivi de la frappe
      du caractère <quote>ESC</quote>. <emphasis role="bold">Le contexte par
      défaut étant celui de fichiers</emphasis>.</para>

      <para>Supposons, par exemple, que le contenu du répertoire courant soit
      le suivant :</para>

      <para><programlisting width="80">

_merge.pl       check.pl             fdate.sh             mytest.pl
_pidof.pl       crlf.pl              gen-meta-index.pl    replace_header_html.pl
_split.pl       extract.pl           idle.pl              rotate.pl
_test.pl        extract_piste.sh     logfile-1.2.pl       rsync.pl
bidir.pl        fcomp.sh             mylock.sh

</programlisting></para>

      <para>Alors la séquence suivante : <computeroutput> $ ls l&lt;ESC&gt;
      </computeroutput> est résolue en (seule correspondance possible) :
      <computeroutput> $ ls logfile-1.2.pl </computeroutput></para>

      <para>Tandis que la séquence ci-contre : <computeroutput> $ ls
      ext&lt;ESC&gt; </computeroutput> est résolue partiellement en :
      <computeroutput> $ ls extract </computeroutput> suivit de l'émission
      d'un bip qui signale que cette expansion est incomplète puisque deux
      fichiers correspondent au préfixe saisi. La commande précédente suivie
      du <command>&lt;CTRL&gt;-D</command> permet d'obtenir l'ensemble des
      réponses potentielles :</para>

      <para><programlisting width="80">

$ ls extract&lt;CTRL&gt;-D                                                            
extract.pl*       extract_piste.sh*
$ ls extract

</programlisting> La saisie d'un seul caractère supplémentaire permet dans ce
      dernier cas de lever l'ambiguïté.</para>

      <para>L'utilisation du bip (sonnerie du terminal) pour signaler des
      erreurs ou des correspondances potentielles peut être désactivée par le
      positionnement de la variable <command>nobeep</command>. Enfin, il est
      possible de limiter les correspondances potentielles à la
      <foreignphrase>completion</foreignphrase> en positionnant la variable
      <command>fignore</command>. Dans l'exemple suivant, on exclut des
      correspondances possibles les fichiers suffixés en
      <command>.o</command>, <command>.out</command> et
      <command>*~</command>.</para>

      <para><programlisting width="80">

$ set fignore = (.o .out *~)                                                    

</programlisting></para>

      <formalpara>
        <title>Contexte utilisateur :</title>

        <para>le mécanisme de <foreignphrase>completion</foreignphrase> peut
        être utilisé pour compléter les noms d'utilisateurs. Il faut utiliser
        le préfixe <command>~</command> (il change le contexte de la
        <foreignphrase>completion</foreignphrase>) : <programlisting
        width="80">

$ cd ~sys&lt;ESC&gt;                                                                   
$ cd ~sysop

</programlisting></para>
      </formalpara>
    </sect2>

    <sect2>
      <title>Navigation dans les répertoires</title>

      <sect3>
        <title>Commandes <command>cd</command></title>

        <para>Supposons qu'un utilisateur ait souvent besoin de se rendre
        alternativement dans le répertoire <filename>/home/cvsroot/</filename>
        et dans son propre répertoire <filename>~/elemntBase</filename>, il
        peut alors :</para>

        <itemizedlist>
          <listitem>
            <para>pour se rendre en
            <filename>/home/cvsroot/C-network/</filename>, taper :</para>
          </listitem>
        </itemizedlist>

        <para><programlisting width="80">

$ cd /home/cvsroot/C-network                                                    

</programlisting></para>

        <itemizedlist>
          <listitem>
            <para>et pour se rendre en <filename>~/elemntBase</filename>,
            taper :</para>
          </listitem>
        </itemizedlist>

        <para><programlisting width="80">

$ cd ~/elemntBase                                                                  
                                                              
</programlisting></para>

        <para>Mais, cet utilisateur peut aussi se simplifier la vie en
        positionnant la variable <command>cdpath</command>, ainsi :</para>

        <para><programlisting width="80">

$ set cdpath = ( /home/cvsroot ~ )                                              

</programlisting></para>

        <para>Ainsi, il peut se contenter de : <itemizedlist>
            <listitem>
              <para>taper dans le premier cas :</para>
            </listitem>
          </itemizedlist></para>

        <para><programlisting width="80">

$ cd C-network                                                                  
/home/cvsroot/C-network

</programlisting></para>

        <itemizedlist>
          <listitem>
            <para>et dans le second :</para>
          </listitem>
        </itemizedlist>

        <para><programlisting width="80">

$ cd elemntBase                                                                    
~/elemntBase

</programlisting></para>
      </sect3>

      <sect3>
        <title>Pile de répertoires : <command>pushd</command>,
        <command>popd</command> et <command>dirs</command></title>

        <para>Une pile est une structure de données qui permet de mémoriser
        des entrées et dont la stratégie d'accès est de type
        <foreignphrase><acronym>LIFO</acronym></foreignphrase>
        (<foreignphrase>Last In, First Out</foreignphrase>),
        <abbrev>i.e.</abbrev> on accède uniquement au sommet de la
        pile.</para>

        <para>La pile des répertoires est gérée par les trois primitives
        suivantes : <itemizedlist>
            <listitem>
              <para>La commande <command>pushd</command> qui permet de changer
              de répertoire (comme <command>cd</command>), en conservant
              l'ancien répertoire dans la pile (il est empilé).</para>
            </listitem>

            <listitem>
              <para>La commande <command>popd</command> qui permet de changer
              de répertoire (comme <command>cd</command>), en dépilant le
              sommet de la pile.</para>
            </listitem>

            <listitem>
              <para>La commande <command>dirs</command> qui permet d'afficher
              le contenu de la pile.</para>
            </listitem>
          </itemizedlist></para>

        <para>L'exemple suivant permet d'en comprendre le fonctionnement :
        <programlisting width="80"> <!-- linenumbering='numbered' width='80'> -->
$ pwd <co id="com.pwd.1" linkends="pwd1" /> 
/usr/home/.sysop/elemntBase/part4                               

$ pushd /usr/local/etc <co id="com.pushd" linkends="pushd" /> 
/usr/local/etc ~/elemntBase/part4

$ pwd <co id="com.pwd.2" linkends="pwd2" /> 
/usr/local/etc

$ popd <co id="com.popd" linkends="popd" /> 
~/elemntBase/part4

$ pwd <co id="com.pwd.3" linkends="pwd3" /> 
/usr/home/.sysop/elemntBase/part4

$ pushd /usr/local/etc
/usr/local/etc ~/elemntBase/part4

$ pwd 
/usr/local/etc

$ dirs -v <co id="com.dirsv" linkends="dirsv" /> 
0       /usr/local/etc
1       ~/elemntBase/part4

$ more =1/domains.txt <co id="com.more" linkends="more" />
http://167.216.142.116
http://193.128.61.168
http://193.210.156.114

... encore plein de lignes...
</programlisting> <calloutlist>
            <callout arearefs="com.pwd.1" id="pwd1">
              <para>Affiche le chemin courant.</para>
            </callout>

            <callout arearefs="com.pushd" id="pushd">
              <para>Se rend dans le répertoire spécifié et l'empile au sommet
              de la pile.</para>
            </callout>

            <callout arearefs="com.pwd.2" id="pwd2">
              <para>Affiche le chemin courant.</para>
            </callout>

            <callout arearefs="com.popd" id="popd">
              <para>Dépile le sommet et se rend dans le répertoire
              indiqué.</para>
            </callout>

            <callout arearefs="com.pwd.3" id="pwd3">
              <para>Affiche le chemin courant.</para>
            </callout>

            <callout arearefs="com.dirsv" id="dirsv">
              <para>Affiche le contenu de la pile, en commençant par le
              sommet.</para>
            </callout>

            <callout arearefs="com.more" id="more">
              <para>Utilisation de la pile pour lire un fichier situé hors du
              répertoire courant.</para>
            </callout>
          </calloutlist></para>
      </sect3>
    </sect2>

    <sect2>
      <title>Gestion des processus</title>

      <sect3>
        <title>Les processus</title>

        <para>Un processus est l'instance d'un programme en exécution. C'est
        une structure de données qui contient du code statique, des données
        statiques et dynamiques et un environnement d'exécution. Un processus
        possède un cycle de vie marqué par des états comme l'exécution
        (<foreignphrase>runnable</foreignphrase>), la suspension, l'attente,
        le sommeil, l'état zombie... Pour se voir allouer des tranches de
        temps (<foreignphrase>time slice</foreignphrase>) d'exécution sur le
        <foreignphrase>CPU</foreignphrase>, un processus doit être dans l'état
        exécutable.</para>

        <para>Chaque programme démarré par le <command>shell</command>
        nécessite la création d'un nouveau processus, on a ainsi une
        arborescence de processus, puisqu'une nouvelle instance ne possède
        qu'un seul parent. L'utilitaire <command>ps</command> permet d'obtenir
        un instantané des processus en cours</para>

        <programlisting width="132">
$ &gt; ps 
  PID <co id="com.pid" linkends="pid" />  TT <co id="com.tt" linkends="tt" />  STAT <co
            id="com.stat" linkends="stat" />      TIME<co id="com.time"
            linkends="time" /> COMMAND <co id="com.command" linkends="command" />

13123      p0-    I      0:03.58 xdiary
13124      p0-    I      0:00.31 xdalarm -cmdPipeId /var/tmp/tmp.0.B2ekTh
15124      p0     Is     0:00.28 -tcsh (tcsh)
16108      p0     S+     0:00.10 /usr/local/bin/wget -NSc ftp://ftp.openbsd.org/
15185      p1     Ss     0:00.38 -tcsh (tcsh)
15263      p1     S      0:43.71 xemacs C-csh_n_tcsh.xml (xemacs-21.1.14)
16109      p1     R+     0:00.00 ps
14204      p2     Is+    0:00.09 ssh -p 3322 -v pascal@Turing.corto.home
15534      p4     I+     0:00.28 mutt
52875      p4     Is     0:00.25 -tcsh (tcsh)
50861      p5     Is     0:00.25 -tcsh (tcsh)

</programlisting>

        <calloutlist>
          <callout arearefs="com.pid" id="pid">
            <para><foreignphrase>Process Identifier</foreignphrase>,
            identifiant (unique) du processus.</para>
          </callout>

          <callout arearefs="com.tt" id="tt">
            <para><foreignphrase>TTy device</foreignphrase>, terminal
            d'exécution.</para>
          </callout>

          <callout arearefs="com.stat" id="stat">
            <para><foreignphrase>STATus</foreignphrase>, état du
            processus</para>
          </callout>

          <callout arearefs="com.time" id="time">
            <para><foreignphrase>TIME consumed</foreignphrase>, temps
            <foreignphrase>CPU</foreignphrase> consommé.</para>
          </callout>

          <callout arearefs="com.command" id="command">
            <para>La commande exécutée.</para>
          </callout>
        </calloutlist>

        <para>Le système identifie chaque processus au moyen d'un entier
        appelé <foreignphrase>pid</foreignphrase>. Dans l'exemple précédent,
        la dernière ligne identifie le processus 50861 qui est un
        <command>shell</command> (<command>tcsh</command>) dans l'état
        <foreignphrase>idle</foreignphrase>, <abbrev>i.e.</abbrev> en sommeil
        depuis plus de 20 secondes, sur le terminal
        <command>/dev/ttyp5</command>.</para>

        <para>La consultation du <command>man 1 ps</command> permet d'obtenir
        une explication complète de la commande. Je rappelle ici la sémantique
        <emphasis>BSD</emphasis> associée au premier caractère de la colonne
        <foreignphrase>STAT</foreignphrase> : <table>
            <title>Sens des éléments de la colonne
            <foreignphrase>STAT</foreignphrase></title>

            <!-- one of (graphic mediaobject tgroup) -->

            <tgroup align="left" cols="2">
              <colspec colname="c1" colnum="1" colwidth="1*+1" />

              <colspec colname="c2" colnum="2" colwidth="3*+1" />

              <thead>
                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center">Caractère</entry>

                  <entry align="center">Sémantique</entry>
                </row>
              </thead>

              <tbody>
                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center">D</entry>

                  <entry>Processus en attente d'une E/S disque.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center">I</entry>

                  <entry>Processus en sommeil depuis plus de 20
                  secondes.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center">R</entry>

                  <entry>Processus en exécution sur le
                  <foreignphrase>CPU</foreignphrase>.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center">S</entry>

                  <entry>Processus en sommeil depuis moins de 20
                  secondes.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center">T</entry>

                  <entry>Processus suspendu (stoppé)</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry align="center">Z</entry>

                  <entry>Processus Zombie</entry>
                </row>
              </tbody>
            </tgroup>
          </table> Des caractères additionnels permettent d'avoir des
        informations supplémentaires, citons le <command>+</command> qui
        indique un processus d'avant plan (interactif
        [<foreignphrase>foreground</foreignphrase>]) parmi le groupe de
        processus contrôlé par un terminal.</para>

        <para>La commande <command>ps l</command> (<abbrev>c.f.</abbrev>
        exemple suivant) permet d'obtenir plus de détails sur les processus.
        On y trouve les paramètres suivants : <itemizedlist>
            <listitem>
              <para>l'<foreignphrase>uid</foreignphrase> : propriétaire du
              processus,</para>
            </listitem>

            <listitem>
              <para>le <foreignphrase>pid</foreignphrase> : identifiant du
              processus,</para>
            </listitem>

            <listitem>
              <para>le <foreignphrase>ppid</foreignphrase> : identifiant du
              père du processus,</para>
            </listitem>

            <listitem>
              <para>le <foreignphrase>cpu</foreignphrase> : estimation du
              temps <foreignphrase>CPU</foreignphrase> consommé,</para>
            </listitem>

            <listitem>
              <para>le <foreignphrase>pri</foreignphrase> :
              <abbrev>i.e.</abbrev> priorité d'ordonnancement,</para>
            </listitem>

            <listitem>
              <para>le <foreignphrase>nice</foreignphrase> : priorité assignée
              par <command>nice</command> ; la modification de cette valeur
              permet d'influer sur l'algorithme d'ordonnancement
              [<foreignphrase>scheduling</foreignphrase>],</para>
            </listitem>

            <listitem>
              <para>le <foreignphrase>vsz</foreignphrase> : donne la taille de
              la mémoire virtuelle utilisée (exprimée en kilo-octet),</para>
            </listitem>

            <listitem>
              <para>le <foreignphrase>rss</foreignphrase> : taille de la
              mémoire réelle utilisée (exprimée en kilo-octet).</para>
            </listitem>

            <listitem>
              <para>le <foreignphrase>wchan</foreignphrase> : le canal
              d'attente, <abbrev>i.e.</abbrev> l'adresse d'une structure de
              données identifiant la ressource ou l'évènement pour lequel le
              processus est en attente,</para>
            </listitem>

            <listitem>
              <para>le <foreignphrase>state</foreignphrase> : état du
              processus parmi (R, S, I, Z ...),</para>
            </listitem>

            <listitem>
              <para>le <foreignphrase>tt</foreignphrase> : le terminal associé
              au processus,</para>
            </listitem>

            <listitem>
              <para>le <foreignphrase>time</foreignphrase> : temps
              <foreignphrase>cpu</foreignphrase> accumulé (utilisateur et
              système),</para>
            </listitem>

            <listitem>
              <para>enfin la commande elle-même.</para>
            </listitem>
          </itemizedlist></para>

        <programlisting width="110">

$ ps l
UID   PID  PPID CPU PRI NI   VSZ   RSS   WCHAN  STAT  TT     TIME COMMAND
666 13123     1   0   2  0  6424  5212   poll   S     p0- 0:07.40 xdiary
666 13124 13123   0   2  0  4956  3132   poll   S     p0- 0:00.76 xdalarm -cmdPi
666 15185 15182   0  18  0  2048  1684   pause  Ss    p1  0:00.57 -tcsh (tcsh)
666 20568 15185   0   2  0 13820  12388  poll   S     p1  0:05.60 xemacs C-csh_n
666 20596 15185   0  28  0   420   208   -      R+    p1  0:00.00 ps -l
666 14204 14203   0   2  0  2080  1500   select Ss+   p2  0:00.19 ssh -p 3322 -v
666 17975 17972   0   3  0  2048  1676   ttyin  Is+   p3  0:00.22 -tcsh (tcsh)
666 19717 52875   0   2  0  3868  2932   poll   S+    p4  0:00.42 mutt
666 52875 52872   0  18  0  2044  1664   pause  Is    p4  0:00.25 -tcsh (tcsh)
666 50861 50858   0  18  0  2044  1672   pause  Is    p5  0:00.26 -tcsh (tcsh)

</programlisting>

        <para>L'invocation d'un programme déclenche un nouveau processus
        chargé de son exécution et pendant ce temps, le
        <foreignphrase>shell</foreignphrase> (père du processus) est suspendu
        jusqu'à la terminaison de ce processus. On parle alors d'éxecution
        interactive (ou en avant-plan
        [<foreignphrase>foreground</foreignphrase>]). Il est évidement
        possible d'exécuter un processus de manière asynchrone
        [<foreignphrase>background</foreignphrase>], <abbrev>i.e.</abbrev> de
        permettre au <foreignphrase>shell</foreignphrase> d'exécuter de
        nouvelles commandes immédiatement. Il suffit pour se faire de
        postfixer la commande à exécuter de manière asynchrone par le
        caractère <quote>ampersand</quote> : &amp;. Voici un exemple (noter le
        numéro du processus : 20713) : <programlisting width="80">

$ fetchmail &amp;                                                                   
[2] 20713

</programlisting></para>

        <para><command><emphasis>csh</emphasis></command> a introduit la
        notion de suspension d'un processus interactif par la commande
        <command>^Z</command> (lire <command>&lt;CTRL&gt;-Z</command>). La
        reprise peut se faire de manière asynchrone (arrière plan) par la
        commande <command>bg</command> ou de manière interactive (avant plan)
        avec la commande symétrique <command>fg</command>.</para>

        <para>Pour finir, signalons la commande <command>top</command> qui
        permet d'avoir des informations en temps réel sur les processus
        (rafraîchissement toutes les 2 secondes). En voici un exemple tronqué
        : <programlisting width="80">

last pid: 21084;  load averages:  0.08,  0.03,  0.01     up 15+03:11:37  23:13:33
56 processes:  1 running, 54 sleeping, 1 stopped
CPU states:  3.5% user,  0.0% nice,  4.7% system,  1.2% interrupt, 90.7% idle
Mem: 365M Active, 430M Inact, 124M Wired, 48M Cache, 112M Buf, 37M Free
Swap: 4096M Total, 48K Used, 4096M Free

  PID USERNAME PRI NICE  SIZE    RES STATE    TIME   WCPU    CPU COMMAND
50627 root       2   0   143M   141M select  80:43  1.90%  1.90% XFree86
50670 pascal     2   0  7960K  5000K poll   100:08  1.86%  1.86% gkrellm
15182 pascal     2   0  6660K  5488K select   0:03  0.78%  0.78% Eterm
15164 pascal     2   0 15416K  9872K poll    34:27  0.05%  0.05% xmms
51005 pascal     2   0   126M   118M poll    20:16  0.00%  0.00% mozilla-bin
50675 pascal     2   0  2052K  1452K select   8:44  0.00%  0.00% wmmatrix
  208 root       2   0  3940K  2992K select   2:41  0.00%  0.00% cupsd
50674 pascal    10   0  2104K  1544K nanslp   2:04  0.00%  0.00% wmitime
50647 pascal     2   0  5484K  3996K select   1:51  0.00%  0.00% wmaker
15168 pascal    10   0  2344K  1684K nanslp   1:14  0.00%  0.00% wmmixer
20568 pascal     2   0 14992K 13912K poll     0:40  0.00%  0.00% xemacs-21.1.14
  312 nobody    10   0  2288K  1296K nanslp   0:29  0.00%  0.00% cups-polld
50727 pascal     2   0  2844K  2284K poll     0:16  0.00%  0.00% xscreensaver
  274 mysql      2  11 27016K  3632K poll     0:09  0.00%  0.00% mysqld
50721 pascal     2   0  1780K  1076K select   0:09  0.00%  0.00% root-tail
13123 pascal     2   0  6424K  4984K poll     0:08  0.00%  0.00% xdiary
  181 root       2   0  2204K   988K select   0:06  0.00%  0.00% master
50858 pascal     2   0  7032K  5772K select   0:06  0.00%  0.00% Eterm
52872 pascal     2   0  5564K  4312K select   0:05  0.00%  0.00% Eterm
   88 root       2   0   944K   556K select   0:04  0.00%  0.00% syslogd
   96 root      10   0   988K   480K nanslp   0:03  0.00%  0.00% cron
50713 pascal     2   0  3236K  1524K select   0:03  0.00%  0.00% fetchmail
  183 postfix    2   0  2260K  1052K select   0:03  0.00%  0.00% qmgr
50662 pascal     2   0  1944K  1240K select   0:02  0.00%  0.00% ssh-agent
16122 root       2   0 15036K  8456K select   0:02  0.00%  0.00% Xvfb
52911 pascal     2   0  1220K   760K select   0:01  0.00%  0.00% esd

</programlisting></para>
      </sect3>

      <sect3>
        <title>Les signaux</title>

        <para>Les signaux sont une forme limitée de communication
        inter-processus. Ils permettent de prévenir les processus de
        l'occurence de certains évènements. Il est possible d'envoyer des
        signaux à des processus interactifs à partir du clavier. La commande
        suivante permet de connaître les associations clés/signaux :
        <programlisting width="80">

$ stty -a                                                                       
speed 38400 baud; 50 rows; 132 columns;
lflags: icanon isig iexten echo echoe echok echoke -echonl echoctl
        -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo          
        -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff -ixany imaxbel -ignbrk
        brkint -inpck ignpar -parmrk
oflags: opost onlcr -ocrnl -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd -hupcl -clocal -cstopb -crtscts
        -dsrflow -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = &lt;undef&gt;;
        eol2 = &lt;undef&gt;; erase = ^?; erase2 = ^@; intr = ^C; kill = ^U;
        lnext = ^V; min = 1; quit = ^\; reprint = ^R; start = ^Q;
        status = ^T; stop = ^S; susp = ^Z; time = 0; werase = ^W;

</programlisting> Ainsi, la séquence &lt;CTRL&gt;-C (<command>^C</command>)
        permet d'envoyer le signal de terminaison (<foreignphrase>INT
        signal</foreignphrase>), la séquence &lt;CTRL&gt;-\
        (<command>^\</command>) permet d'envoyer un autre signal de
        terminaison (<foreignphrase>QUIT</foreignphrase>), la séquence
        &lt;CTRL&gt;-Z (<command>^Z</command>) permet d'envoyer le signal de
        suspension (<foreignphrase>TSTP</foreignphrase>). Par défaut, les deux
        premiers signaux (INT et QUIT) termine le processus, tandis que le
        troisième ne fait que suspendre l'éxecution, <abbrev>i.e.</abbrev>
        elle peut donc être reprise. Ce comportement par défaut peut cependant
        être redéfini au sein d'un processus.</para>

        <para>Sur une architecture <foreignphrase>4.4BSD</foreignphrase>
        (FreeBSD, NetBSD, OpenBSD) on trouve 31 signaux. La commande,
        improprement nommée <command>kill</command> (<computeroutput>man 1
        kill</computeroutput>) permet d'envoyer des signaux à un processus. Sa
        syntaxe est la suivante : <command>kill &lt;signal&gt;
        &lt;pus&gt;</command>, où &lt;signal&gt; est le signal envoyé au
        processus de numéro &lt;pus&gt;</para>

        <para>La liste des signaux délivrable par la commande
        <command>kill</command> peut être obtenue de la manière suivante :
        <programlisting width="80">

$ kill -l                                                                       
HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP     
TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2 

</programlisting> Parmi ces signaux, deux ne peuvent être ni ignorés, ni
        détournés. Il s'agit du <command>KILL</command> (terminaison) et du
        <command>STOP</command> (suspension ou stop) (à ne pas confondre avec
        le <command>TSTP</command> vu précédemment).</para>
      </sect3>

      <sect3>
        <title>Jobs</title>

        <para>Cette notion inventée par la branche <emphasis>BSD</emphasis>
        d'<productname>Unix</productname> et introduite par
        <command><emphasis>csh</emphasis></command> est désormais disponible
        sur toutes les distributions <productname>Unix</productname>
        <emphasis>libres</emphasis>.</para>

        <para>Un <foreignphrase>job</foreignphrase> est soit un processus,
        soit un groupe de processus lancé par le
        <foreignphrase>shell</foreignphrase>. Un
        <foreignphrase>job</foreignphrase> peut être suspendu, redémarré,
        terminé, executé interactivement ou de manière asynchrone. Le
        <foreignphrase>shell</foreignphrase> sait gérer plusieurs
        <foreignphrase>jobs</foreignphrase> simultanément, toutefois à un
        instant donné seul un <foreignphrase>job</foreignphrase> peut avoir
        accès au terminal. Les <foreignphrase>jobs</foreignphrase> sont
        intéressants dès que les processus qu'ils contrôlent ont une durée de
        vie de quelques secondes. Analysons la séquence suivante :
        <programlisting width="80">
$ su toor <co id="com.su" linkends="su" /> 
Password:
# id
uid=0(root) gid=0(wheel) groups=0(wheel)
# suspend <co id="com.susp" linkends="susp" /> 

Suspended
$ jobs <co id="com.job1" linkends="job1" />
[1]  - Running                xemacs C-csh_n_tcsh.xml
[2]  + Suspended              su toor
$ du -s -h /usr &amp; <co id="com.async" linkends="async" />
[3] 21136
$ ls3.7G    /usr <co id="com.rep" linkends="rep" />
[3]    Exit 1                 du -s -h /usr <co id="com.exit" linkends="exit" />
$ ls /usr 
C-csh_n_tcsh.xml Makefile         _mystyle.xsl     images           my_style.xsl
CVS              _mystyle.css     html             my_print.dsl

$ stty tostop <co id="com.async2" linkends="async2" />
$ du -s -h /usr &amp;

...

$ jobs
[1]    Running                       xemacs C-csh_n_tcsh.xml
[2]  - Suspended                     su toor
[3]  + Suspended (tty output)        du -s -h /usr <co id="com.notif"
              linkends="notif" />

$ %3 <co id="com.rep2" linkends="rep2" />
du -s -h /usr
3.7G    /usr

$ jobs
[1]  - Running                       xemacs C-csh_n_tcsh.xml
[2]  + Suspended                     su toor

$ %2
# exit <co id="com.rep3" linkends="rep3" />
$ jobs
[1]  + Running                       xemacs C-csh_n_tcsh.xml
</programlisting> <calloutlist>
            <callout arearefs="com.su" id="su">
              <para>Changement d'identité utilisateur.</para>
            </callout>

            <callout arearefs="com.susp" id="susp">
              <para>Suspension du processus et restauration de l'identité
              précédente.</para>
            </callout>

            <callout arearefs="com.job1" id="job1">
              <para>Liste des <foreignphrase>jobs</foreignphrase> en
              cours;</para>
            </callout>

            <callout arearefs="com.async" id="async">
              <para>Lancement d'une nouvelle commande, <abbrev>i.e.</abbrev>
              un processus de manière asynchrone, celui ci écrira son éventuel
              résultat sur la sortie standard, sans se préoccuper de ce qu'il
              peut se passer !</para>
            </callout>

            <callout arearefs="com.rep" id="rep">
              <para>Le résultat de la commande <command>du</command> survient
              au moment où l'utilisateur tape sa commande
              <command>ls</command> et pertube donc son affichage.</para>
            </callout>

            <callout arearefs="com.exit" id="exit">
              <para>Terminaison du processus. La commande
              <command>ls</command> s'affiche alors.</para>
            </callout>

            <callout arearefs="com.async2" id="async2">
              <para>Pour éviter le mélange précédent, nous bloquons l'écriture
              du résultat de la commande sur le terminal.</para>
            </callout>

            <callout arearefs="com.rep2" id="rep2">
              <para>Le comportement du processus change, l'utilisateur est
              informé (variable <command>notify</command> de
              <emphasis>csh</emphasis>, <abbrev>c.f.</abbrev> <quote><xref
              linkend="envvar" /></quote>) que le
              <foreignphrase>job</foreignphrase> 3 est prêt à imprimer son
              résultat (il est suspendu jusqu'à ce qu'il soit autorisé à la
              faire).</para>
            </callout>

            <callout arearefs="com.notif" id="notif">
              <para>On rappelle le <foreignphrase>job</foreignphrase> 3, ce
              qui lui permet d'afficher son résultat.</para>

              <para>Un <foreignphrase>job</foreignphrase> asynchrone qui veut
              lire sur l'entrée standard alors que ce canal n'a pas été
              redirigé est toujours suspendu. Il faut le relancer de manière
              interactive pour qu'il puisse collecter ses données sur l'entrée
              standard.</para>
            </callout>

            <callout arearefs="com.rep3" id="rep3">
              <para>On rappelle le <foreignphrase>job</foreignphrase> 2 et on
              le termine explicitement par un <command>exit</command>. Il
              reste alors un seul <foreignphrase>job</foreignphrase> en
              exécution asynchrone.</para>
            </callout>
          </calloutlist></para>

        <para>La liste des <foreignphrase>jobs</foreignphrase> en cours est
        donné par la commande <command>jobs</command>.</para>

        <para>Le caractère % en première position dénote un
        <foreignphrase>job</foreignphrase>.</para>

        <para>Le tableau suivant (<abbrev>c.f.</abbrev> <quote><xref
        linkend="tab05" /></quote>) récapitule les différentes manières de
        référencer un <foreignphrase>job</foreignphrase>. <table id="tab05">
            <title>référencement des
            <foreignphrase>jobs</foreignphrase></title>

            <!-- one of (graphic mediaobject tgroup) -->

            <tgroup align="left" cols="2">
              <colspec colname="c1" colnum="1" colwidth="1*+1" />

              <colspec colname="c2" colnum="2" colwidth="3*+1" />

              <thead>
                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry>Expression</entry>

                  <entry>Sémantique</entry>
                </row>
              </thead>

              <tbody>
                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry>%n</entry>

                  <entry><foreignphrase>job</foreignphrase> numéro
                  <emphasis>n</emphasis>.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry>%str</entry>

                  <entry><foreignphrase>job</foreignphrase> commençant par la
                  chaine <emphasis>str</emphasis>.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry>%?str</entry>

                  <entry><foreignphrase>job</foreignphrase> contenant la
                  chaine <emphasis>str</emphasis>.</entry>
                </row>
              </tbody>
            </tgroup>
          </table></para>

        <para>Le tableau suivant (<abbrev>c.f.</abbrev> <quote><xref
        linkend="tab06" /></quote>) donne les commandes de contrôle d'un
        <foreignphrase>job</foreignphrase>. <table id="tab06">
            <title>Commandes contrôlant les
            <foreignphrase>jobs</foreignphrase></title>

            <!-- one of (graphic mediaobject tgroup) -->

            <tgroup align="left" cols="2">
              <colspec colname="c1" colnum="1" colwidth="1*+1" />

              <colspec colname="c2" colnum="2" colwidth="3*+1" />

              <thead>
                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry>Expression</entry>

                  <entry>Sémantique</entry>
                </row>
              </thead>

              <tbody>
                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry><command>bg [name]</command></entry>

                  <entry><para>Place le job <emphasis>name</emphasis> en
                  exécution asynchrone. </para> <para>Si l'argument
                  <emphasis>name</emphasis> n'est pas précisé, la commande
                  s'applique au <foreignphrase>job</foreignphrase>
                  courant.</para></entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry><command>name &amp;</command></entry>

                  <entry>Place le job <emphasis>name</emphasis> en exécution
                  asynchrone.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry><command>fg [name]</command></entry>

                  <entry><para>Place le job <emphasis>name</emphasis> en
                  exécution interactive.</para> <para>Si l'argument
                  <emphasis>name</emphasis> n'est pas précisé, la commande
                  s'applique au <foreignphrase>job</foreignphrase>
                  courant.</para></entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry><command>name</command></entry>

                  <entry>Place le job <emphasis>name</emphasis> en exécution
                  interactive.</entry>
                </row>

                <row>
                  <!-- one of (entrytbl entry) -->

                  <entry><command>stop name</command></entry>

                  <entry>Suspend le job <emphasis>name</emphasis>.</entry>
                </row>
              </tbody>
            </tgroup>
          </table></para>

        <para>Enfin, la commande <command>kill</command> permet aussi
        d'envoyer des signaux aux <foreignphrase>jobs</foreignphrase>, en
        utilisant le même référencement des jobs qu'en <quote><xref
        linkend="tab05" /></quote>. Ainsi, la commande suivante met fin au
        <foreignphrase>job</foreignphrase> 1 : <programlisting width="80">

$ kill -TERM %1                                                                 

</programlisting></para>

        <important>
          <para>En <command><emphasis>csh</emphasis></command>, comme en
          <command>tcsh</command> les processus asynchrones ne sont pas
          affectés par un <command>logout</command> puisqu'il n'y a pas
          d'envoi du signal <foreignphrase>HUP</foreignphrase> à l'exécution
          du <command>logout</command>.</para>

          <para>Corollaire : pas besoin de la commande
          <command>nohup</command> des autres
          <foreignphrase>shells</foreignphrase> (tel
          <emphasis>GNU/Bash</emphasis>).</para>
        </important>
      </sect3>

      <sect3>
        <title><command>limit</command></title>

        <para>Cette commande a pour objet de définir des limites à la
        consommation des ressources du système par les processus. Il s'agit
        d'un intervalle définit par une borne haute (<foreignphrase>hard
        limits</foreignphrase> : qui ne peut être modifiée qu'à la baisse,
        sauf par le <emphasis>super</emphasis>-utilisateur et une borne basse
        (<foreignphrase>current limits</foreignphrase> : qui peut être accrue
        jusqu'aux valeurs de la borne haute).</para>

        <para><programlisting width="80">

$ limit         # affichage des limites courantes                               
cputime         unlimited
filesize        unlimited
datasize        262144 kbytes
stacksize       262144 kbytes
coredumpsize    0 kbytes
memoryuse       unlimited
vmemoryuse      unlimited
descriptors     2048 
memorylocked    unlimited
maxproc         1024 
sbsize  unlimited

$ limit coredumpsize 1024 # augmenter la limite basse d'un fichier core à 1024k 

$ limit maxproc 2048 # augmenter le nb max de proc concurrents
limit: maxproc: Can't set limit (Operation not permitted)

$ limit maxproc 512    # augmenter le nb max de proc concurrents (lim. cour.)
$ limit -h maxproc 784 # augmenter le nb max de proc concurrents (lim. hautes)

$ limit         # affichage des limites courantes                               
cputime         unlimited
filesize        unlimited
datasize        262144 kbytes
stacksize       262144 kbytes
coredumpsize    1024 kbytes
memoryuse       unlimited
vmemoryuse      unlimited
descriptors     2048 
memorylocked    unlimited
maxproc         512 
sbsize  unlimited

$limit -h       # affichage des limites hautes                               
cputime         unlimited
filesize        unlimited
datasize        262144 kbytes
stacksize       262144 kbytes
coredumpsize    unlimited
memoryuse       unlimited
vmemoryuse      unlimited
descriptors     2048 
memorylocked    unlimited
maxproc         784 
sbsize  unlimited

</programlisting></para>
      </sect3>
    </sect2>

    <sect2 id="sect_redirection_comm">
      <title>Redirection de commandes</title>

      <para>Rapellons que, sous <productname>Unix</productname> en général et
      sous <emphasis role="bold">BSD</emphasis> en particulier, il existe
      trois canaux d'E/S standard : <itemizedlist>
          <listitem>
            <para>L'entrée standard [<foreignphrase>stdin</foreignphrase>]
            associée au fd [<foreignphrase>file descriptor</foreignphrase>]
            <emphasis role="bold">0</emphasis> liée traditionnellement au
            clavier.</para>
          </listitem>

          <listitem>
            <para>La sortie standard [<foreignphrase>stdout</foreignphrase>]
            associée au fd <emphasis role="bold">1</emphasis>, liée
            traditionnellement à l'écran du terminal.</para>
          </listitem>

          <listitem>
            <para>La sortie standard d'erreur
            [<foreignphrase>stderr</foreignphrase>] associée au fd <emphasis
            role="bold">2</emphasis>, liée traditionnellement à l'écran du
            terminal.</para>
          </listitem>
        </itemizedlist> Formellement, un descripteur de fichier est un entier
      non signé utilisé par les processus pour référencer les canaux
      d'E/S.</para>

      <para>La puissance et la flexibilité du concept des canaux standards
      d'E/S tient essentiellement au fait que le
      <foreignphrase>shell</foreignphrase> peut rediriger ces canaux aussi
      bien sur des fichiers, que l'écran ou le clavier.</para>

      <para><table id="redirec">
          <title>Redirections</title>

          <tgroup cols="2">
            <colspec align="left" colname="c1" colnum="1" colwidth="1*+1" />

            <colspec align="left" colname="c2" colnum="2" colwidth="3*+1" />

            <thead valign="middle">
              <row>
                <entry align="center">Symbole</entry>

                <entry align="center">Sémantique</entry>
              </row>
            </thead>

            <tbody>
              <row>
                <entry><command>&gt;</command> &lt;fnom&gt;</entry>

                <entry>La sortie standard est redirigée dans le fichier
                &lt;fnom&gt;. S'il existait, son contenu est perdu et sinon il
                est créé.</entry>
              </row>

              <row>
                <entry><command>&gt;&gt;</command> &lt;fnom&gt;</entry>

                <entry>La sortie standard est redirigée dans le fichier
                &lt;fnom&gt;, ouvert en mode ajout s'il existait, sinon il est
                créé.</entry>
              </row>

              <row>
                <entry><command>&gt;&amp;</command> &lt;fnom&gt;</entry>

                <entry>La sortie d'erreur est redirigée dans le fichier
                &lt;fnom&gt;. S'il existait, son contenu est perdu et sinon il
                est créé.</entry>
              </row>

              <row>
                <entry><command>&gt;&gt;&amp;</command> &lt;fnom&gt;</entry>

                <entry>La sortie d'erreur est redirigée dans le fichier
                &lt;fnom&gt;, ouvert en mode ajout s'il existait, sinon il est
                créé.</entry>
              </row>

              <row>
                <entry><command>&lt;</command> &lt;fnom&gt;</entry>

                <entry>L'entrée standard est le fichier &lt;fnom&gt;.</entry>
              </row>

              <row>
                <entry><command>&lt;&lt;</command> &lt;mot&gt;</entry>

                <entry>Lit les entrées du <foreignphrase>shell</foreignphrase>
                jusqu'à une ligne commençant (et contenant uniquement) le mot
                &lt;mot&gt; qui agit comme un marqueur de fin.</entry>
              </row>
            </tbody>
          </tgroup>
        </table></para>

      <para>Le positionnement de la variable interne
      <varname>noclobber</varname>, permet d'éviter l'écrasement des fichiers
      existants dans le cas de l'utilisation des commandes de redirection
      <command>&gt;</command> et <command>&gt;&amp;</command>. De plus les
      commandes <command>&gt;&gt;</command> et
      <command>&gt;&gt;&amp;</command> ne peuvent être exécutées que sur des
      fichiers existants.</para>

      <para>Enfin, la sémantique initiale des commandes de redirection (après
      activation de <varname>noclobber</varname>) peut être explicitement
      restituée en utilisant le symbole <command>!</command>. Ainsi, les
      commandes <command>&gt;!</command>, <command>&gt;&gt;!</command>,
      <command>&gt;&amp;!</command> et <command>&gt;&gt;&amp;!</command> ont
      un comportement identique à leurs homologues du tableau précédent
      (<abbrev>i.e.</abbrev> sans le <command>!</command>,
      <abbrev>c.f.</abbrev> <quote><xref linkend="redirec" /></quote>).
      <programlisting width="80">
<emphasis>EXEMPLES :</emphasis>

$ cat &gt; file.txt &lt;&lt; fin_de_saisie                                               
&gt;&gt; première ligne
&gt;&gt; puis une 2e
&gt;&gt; Encore une autre !
&gt;&gt; C'est pas fini ...
&gt;&gt; fin_de_saisie

$  ll file.txt
-rw-------  1 pascal  gnu  - 65 Aug 1 15:58 file.txt

$ cat &lt; file.txt  # équivalent à cat file.txt
première ligne
puis une 2e
Encore une autre !
C'est pas fini ...

$ ( find /home -name "*~" -print &gt; fout ) &gt;&amp; ferr
                  # séparer les sorties standard (&gt; fout) et d'erreur (&gt;&amp; ferr) 
$ cat fout        # les résultats
/home/pascal/enseignement/NeoTechIII/V2L-PRAI/CS2-csh/toto.sh~
/home/pascal/enseignement/NeoTechIII/V2L-PRAI/Progr-V2L/Progr-V2L.xml~
/home/miji/work/these/annexes/annexes.sxw~
/home/miji/work/these/partie1/part_legende/legendes.sxw~
/home/hosts/corto-home/turing/postfix/main.cf~
/home/hosts/corto-home/euler/ulocal-etc/flexbackup/flexbackup.conf~
/home/hosts/corto-home/euler/ulocal-etc/tripwire/twpol.txt~
/home/hosts/corto-home/euler/etc/ssh/sshd_config~
/home/hosts/corto-home/tux/etc/apache/httpd.conf~
/home/hosts/corto-home/tux/etc/apache-ssl/httpd.conf~

$ cat ferr        # les erreurs
find: /home/miji/.ssh: Permission denied
find: /home/miji/work/lit_reu/Dayot: Permission denied
find: /home/miji/Choices: Permission denied
find: /home/miji/pdf: Permission denied
find: /home/miji/tmp: Permission denied
find: /home/miji/.Eterm: Permission denied
find: /home/miji/.mozilla: Permission denied
find: /home/miji/.mutt: Permission denied
find: /home/miji/.netscape: Permission denied
find: /home/miji/.prefs: Permission denied
find: /home/miji/.vnc: Permission denied
find: /home/miji/.Gabber: Permission denied
find: /home/miji/.wmakerconf: Permission denied

</programlisting></para>
    </sect2>

    <sect2>
      <title>Tubes [<foreignphrase>Pipelines</foreignphrase>]</title>

      <para>Le mécanisme de <foreignphrase>pipeline</foreignphrase> consiste à
      rediriger la sortie d'une commande vers l'entrée d'une autre. D'un point
      de vue syntaxique nous avons la structure suivante : <programlisting
      width="80">

&lt;commandA&gt; | &lt;commandB&gt;                                                         

</programlisting> <example id="ex_pipe">
          <title>Utilisation du mécanisme de
          <foreignphrase>pipeline</foreignphrase></title>

          <para><programlisting width="80">

$ ls -l | sort -k 5n                                                            

</programlisting> La sortie de la commande <command>ls -l</command> est
          redirigée vers l'entrée de la commande <command>sort -k
          5n</command>.</para>
        </example></para>

      <qandaset defaultlabel="qanda">
        <qandaentry>
          <question>
            <para>Que permet de réaliser la commande précédente ?</para>
          </question>

          <answer>
            <para></para>

            <!-- tri numérique (ordre croissant) du répertoire (listing au format long) sur le 5e champ, i.e. la taille en octet -->
          </answer>
        </qandaentry>
      </qandaset>

      <para>Enfin, en postfixant au tube ('|' ou encore
      <foreignphrase>pipe</foreignphrase>)
      l'<foreignphrase>ampersand</foreignphrase> (&amp;), il est possible de
      combiner les sorties standard et d'erreur vers l'entrée de la commande
      qui suit (le tube). <programlisting width="80">

&lt;commandA&gt; |&amp; &lt;commandB&gt;                                                        

</programlisting></para>
    </sect2>
  </sect1>

  <!-- 3e partie -->

  <sect1>
    <title>Structures de Contrôle &amp; autres éléments algorithmiques</title>

    <para>Ces structures algorithmiques sont utilisées dans les scripts
    <foreignphrase>shell</foreignphrase>s. Pour rédiger un script
    <foreignphrase>shell</foreignphrase> (ici, en <emphasis>tcsh</emphasis>),
    il faut : <orderedlist>
        <listitem>
          <para>Créer le fichier avec un éditeur de texte
          (<filename>sample.sh</filename>). La première ligne doit commencer
          avec le prologue [<foreignphrase>shebang</foreignphrase>] :
          <command>#!/bin/tcsh</command>.</para>
        </listitem>

        <listitem>
          <para>Lui attribuer la permission d'exécution sur le fichier créé
          (<computeroutput>chmod +x sample.sh</computeroutput>).</para>
        </listitem>

        <listitem>
          <para>Enfin, pour l'exécuter il suffit de taper le nom du fichier,
          puisque c'est désormais une nouvelle commande (si on est dans le
          répertoire courant de cette commande, il suffit de taper
          <computeroutput>./sample.sh</computeroutput>).</para>
        </listitem>
      </orderedlist> Nous donnons dans ce qui suit, quelques exemples de
    scripts <foreignphrase>shell</foreignphrase>s
    (<emphasis>csh</emphasis>).</para>

    <sect2>
      <title>Alternatives</title>

      <!-- IF -->

      <sect3>
        <title>La structure alternative <command>if</command></title>

        <para>Cette structure permet l'exécution conditionnelle d'une
        instruction. Voici sa syntaxe :</para>

        <para><programlisting width="80">

if ( &lt;condition&gt; ) then                                                         
  &lt;liste instructions&gt;
else if ( &lt;condition&gt; ) then
  &lt;liste instructions&gt;
else if ( &lt;condition&gt; ) then
  &lt;liste instructions&gt;
else
  &lt;liste instructions&gt;
endif

</programlisting></para>

        <para><example id="ex_if">
            <title>Utilisation du if</title>

            <programlisting width="80">

#!/bin/csh
# /home/pascal/bin/fcomp.sh
#
# but : comparer deux fichiers
#
#                                      [Sept. 2002]   

if ( ${#argv} != 2 ) then
    echo "usage : $0 file1 file2"
    echo "compare deux fichiers file1 et file2 et dit s'ils sont identiques ou \
differents."
    exit -1
endif

cmp $argv[1] $argv[2] &gt;&amp; /dev/null
set ret = $?
if ( $ret == 0 ) then
    echo "Les fichiers $argv[1] et $argv[2] sont identiques."
else if ( $ret == 1 ) then
    echo "Les fichiers $argv[1] et $argv[2] sont differents."
else
    echo "Une erreur est survenue !"
endif
exit $ret

</programlisting>
          </example> <example>
            <title>Résultat du code de <xref linkend="ex_if" /></title>

            <programlisting width="80">

$ ~/bin/fcomp.sh                                                                
usage : /home/pascal/bin/fcomp.sh file1 file2
compare deux fichiers file1 et file2 et dit s'il sont identiques ou differents. 

$ ~/bin/fcomp.sh ~/bin/fdate.sh ~/bin/fcomp.sh
Les fichiers /home/pascal/bin/fdate.sh et /home/pascal/bin/fcomp.sh sont differe
nts.

$ ~/bin/fcomp.sh ~/bin/fdate.sh /etc/shadow
Une erreur est survenue !

</programlisting>
          </example></para>
      </sect3>

      <!-- END IF -->

      <!-- SWITCH -->

      <sect3>
        <title>La structure alternative <command>switch</command></title>

        <para>Cette structure permet l'exécution conditionnelle d'une
        instruction.</para>

        <para><programlisting width="80">

switch ( &lt;variable&gt; )                                                           
  case motif1 :
         &lt;liste instructions&gt;
         breaksw

  case motif2 :
  case motif3 :
         &lt;liste instructions&gt;
         breaksw

  case motif4 :
         &lt;liste instructions&gt;

  case motif5 :
         &lt;liste instructions&gt;

  default:
         &lt;liste instructions&gt;

endsw

</programlisting></para>

        <para><example id="ex_switch">
            <title>Utilisation du switch</title>

            <para><programlisting width="80">
#!/bin/csh
# /home/pascal/bin/fdate.sh
#
# but :  conversion date en francais 
#
#                                      [Sept. 2002]

set res=`date`

# Traiter le jour                                                               
switch ( $res[1] )
    case Mon :
	set day=Lun
	breaksw
    case Tue :
	set day=Mar
	breaksw
    case Wed :
	set day=Mer
	breaksw
    case Thu :
	set day=Jeu
	breaksw
    case Fri :
	set day=Ven
	breaksw
    case Sat :
	set day=Sam
	breaksw
    case Sun :
	set day=Dim
	breaksw
endsw

# Traiter le mois
switch ( $res[2] )
    case Feb :
	set mon=Fev
	breaksw
    case Apr :
	set mon=Avr
	breaksw
    case May :
	set mon=Mai
	breaksw
    case Jun :
	set mon=Juin
	breaksw
    case Jul :
	set mon=Juil
	breaksw
    case Aug :
	set mon=Aou
	breaksw
    case Jan :
    case Sep :
    case Oct :
    case Nov :
    case Dec :
	set mon=$res[2]
	breaksw
endsw

# Afficher le resultat
echo "$day $res[3] $mon $res[6], $res[4] [$res[5]]"

</programlisting></para>
          </example> <example>
            <title>Résultat du code de <xref linkend="ex_switch" /></title>

            <programlisting width="80">
$ fdate.sh                                                                      
Sam 12 Avr 2003, 21:20:45 [RET]
</programlisting>
          </example></para>
      </sect3>

      <!-- END SWITCH -->
    </sect2>

    <sect2>
      <title>Boucles</title>

      <!-- WHILE -->

      <sect3>
        <title>Boucle <command>while</command></title>

        <para>Il s'agit de l'instruction standard qui permet d'exécuter le
        corps de la boucle tant que la condition d'entrée est vérifiée (valeur
        évaluée à vrai).</para>

        <para><programlisting width="80">

while ( &lt;condition&gt; )                                                           
  &lt;corps_de_boucle&gt;
end

</programlisting></para>

        <para><example id="ex_while">
            <title>Utilisation du while</title>

            <programlisting width="80">

#!/bin/csh 
# ~/bin/test.sh                                                                 

set ind=1

while ( $ind &lt; 11 )
  @ indcar = $ind * $ind
  echo $ind "  " $indcar
  @ ind++
end

</programlisting>
          </example> <example>
            <title>Résultat du code de <xref linkend="ex_while" /></title>

            <programlisting width="80">

$ ~/bin/test.sh                                                                 
1     1                                                                         
2     4
3     9
4     16
5     25
6     36
7     49
8     64
9     81
10     100

</programlisting>
          </example></para>
      </sect3>

      <!-- END WHILE -->

      <!-- REPEAT -->

      <sect3>
        <title>Boucle <command>repeat</command></title>

        <para>Cette instruction permet de répéter un nombre entier de fois une
        même commande.</para>

        <para><programlisting width="80">

repeat &lt;nombre_de_fois&gt; &lt;commande&gt;                                              

</programlisting></para>

        <para><example id="ex_repeat">
            <title>Utilisation et résultat du
            <command>repeat</command></title>

            <programlisting width="80">

$ repeat 3 echo "hello, world !"                                                
hello, world !                                                                  
hello, world !
hello, world !

</programlisting>
          </example></para>
      </sect3>

      <!-- END REPEAT -->

      <!-- FOREACH -->

      <sect3>
        <title>Boucle <command>foreach</command></title>

        <para>Cette instruction permet de traiter en séquence tous les
        éléments d'une liste.</para>

        <para><programlisting width="80">

foreach &lt;variable&gt; ( &lt;liste_de_valeur&gt; )                                        
  &lt;corps_de_boucle&gt;
end

</programlisting></para>

        <para><example id="ex_foreach">
            <title>Utilisation du <command>foreach</command></title>

            <programlisting width="80">

#!/bin/csh
# ~/bin/test.sh                                                                 

foreach i ( 1 2 3 4 5 6 7 8 9 )                                                 
  @ m = $i * 2
  echo -n " $m"
end
echo

</programlisting>
          </example> <example>
            <title>Résultat du code de <xref linkend="ex_foreach" /></title>

            <programlisting width="80">

$ ~/bin/test.sh                                                                 
2 4 6 8 10 12 14 16 18                                                          
$

</programlisting>
          </example></para>
      </sect3>

      <!-- END FOREACH -->
    </sect2>

    <sect2>
      <title>Variables utilisateurs</title>

      <para>Ce sont les variables que les utilisateurs peuvent définir. Le
      <foreignphrase>shell</foreignphrase> étant un langage interprété non
      typé, aucune déclaration n'est nécessaire et la même variable peut
      contenir tour à tour une chaîne de caractères, un entier, ou un vecteur
      (tableau d'éléments de type chaîne de caractères ou entier, indexé par
      des entiers, commençant à 1).</para>

      <formalpara>
        <title>Affectation</title>

        <para>Cette opération permet d'associer un contenu à une variable (le
        contenant). En <emphasis>csh</emphasis> comme en
        <emphasis>tcsh</emphasis>, l'affectation se fait en utilisant la
        commande interne <command>set</command> de la manière suivante :
        <programlisting width="80">
<emphasis>EXEMPLE :</emphasis>

$ set myvar1 = 10                                                               
$ set myvar2 = "chaine de caractère"
$ 

</programlisting></para>
      </formalpara>

      <formalpara>
        <title>Accès au contenu</title>

        <para>L'accès au contenu de la variable se fait en préfixant le nom de
        la variable par le symbole <emphasis role="bold">$</emphasis>.
        <programlisting width="80">
<emphasis>EXEMPLE (SUITE) :</emphasis>

$ echo $myvar1                                                                  
10
$ echo $myvar2
chaine de caractère

$ echo myvar1     # omission du méta-caractère $
myvar1            # echo affiche le mot myvar1

</programlisting> On peut aussi encadrer la variable par les symboles
        <emphasis role="bold">{</emphasis> et <emphasis
        role="bold">}</emphasis> avant de la préfixer par le symbole <emphasis
        role="bold">$</emphasis> : <programlisting width="80">
<emphasis>EXEMPLE (SUITE) :</emphasis>

$ set si  = "pas "                                                              
$ echo "c'est vraiment $sidrôle"
sidrôle: Undefined variable.   # le $ porte ici sur le mot sidrôle et non sur si
$ echo "c'est vraiment ${si}drôle"
c'est vraiment pas drôle
$

</programlisting> <note>
            <para>L'accès à une variable non définie produit (sauf rares
            exceptions) une erreur (en <emphasis>csh</emphasis>, comme en
            <emphasis>tcsh</emphasis>).</para>
          </note></para>
      </formalpara>

      <formalpara>
        <title>Effacer une variable</title>

        <para>Cette opération permet de libérer la case mémoire occupée par la
        variable. Cela se fait en <emphasis>csh</emphasis> comme en
        <emphasis>tcsh</emphasis>, en utilisant la commande interne
        <command>unset</command> de la manière suivante : <programlisting
        width="80">
<emphasis>EXEMPLE (SUITE) :</emphasis>

$ echo $myvar1                                                                  
10
$ unset myvar1
$ echo $myvar1
myvar1: Undefined variable.
$ 

</programlisting></para>
      </formalpara>

      <formalpara>
        <title>Variable de type vecteur</title>

        <para>Voici un exemple : <programlisting width="80">
<emphasis>CODE :</emphasis>


#!/bin/csh
# ~/bin/testvect.sh

set vect = ( 2 -2 4 -4 6 -6 8 -8 10 -10 ) 

# afficher les elements du vecteur vect, element par element                    
set i = 1
set sum = 0
echo " -  Affichage element par element"
while ( $i &lt;= ${#vect} )
    echo '$vect[' $i '] = ' $vect[$i]
    @ sum = $sum + $vect[$i]
    @ i++
end

echo " - Somme des elements = " $sum

# acc賠par tranche
set j = 5
echo "Voici le vecteur vect (${#vect} elements)         : " $vect[1-]
echo "Voici les $j premiers elements du vecteur    : " $vect[-$j]
echo "Voici les derniers elements ࠰artir du $j e : " $vect[$j-]

# fin du script


<emphasis>EXEMPLE :</emphasis>

$ ./testvect.sh                                                                 
 -  Affichage élément par élément
$vect[ 1 ] =  2
$vect[ 2 ] =  -2
$vect[ 3 ] =  4
$vect[ 4 ] =  -4
$vect[ 5 ] =  6
$vect[ 6 ] =  -6
$vect[ 7 ] =  8
$vect[ 8 ] =  -8
$vect[ 9 ] =  10
$vect[ 10 ] =  -10
 - Somme des elements =  0
Voici le vecteur vect (10 éléments)         :  2 -2 4 -4 6 -6 8 -8 10 -10
Voici les 5 premiers éléments du vecteur    :  2 -2 4 -4 6
Voici les derniers éléments à partir du 5 e :  6 -6 8 -8 10 -10

$

</programlisting></para>
      </formalpara>

      <formalpara>
        <title>Modificateurs de variables</title>

        <para>Les modificateurs [<foreignphrase>modifiers</foreignphrase>]
        suivants peuvent être appliqués aux variables. On travaillera avec
        l'exemple (un vecteur) suivant : <programlisting width="80">

$ set mypath = ( /usr/local/src/foo.c /usr/src/bar.cc )   # un vecteur de path  

</programlisting> <table>
            <title>Clé de modification</title>

            <tgroup cols="3">
              <colspec align="left" colname="c1" colnum="1" colwidth="1*+1" />

              <colspec align="left" colname="c2" colnum="2" colwidth="3*+1" />

              <colspec align="left" colname="c3" colnum="3" colwidth="4*+1" />

              <thead valign="middle">
                <row>
                  <entry align="center">Clé</entry>

                  <entry align="center">Sémantique</entry>

                  <entry align="center">Exemple</entry>
                </row>
              </thead>

              <tbody>
                <row>
                  <entrytbl cols="1">
                    <tbody>
                      <row>
                        <entry><command>:h</command>&nbsp;&nbsp;
                        <command>:gh</command></entry>
                      </row>
                    </tbody>
                  </entrytbl>

                  <entrytbl cols="2">
                    <tbody>
                      <row>
                        <entry>interprète le contenu de la variable comme un
                        nom de fichier <productname>Unix</productname></entry>

                        <entry>et en donne le début, <abbrev>i.e.</abbrev> la
                        partie avant le dernier /</entry>
                      </row>
                    </tbody>
                  </entrytbl>

                  <entry><programlisting width="36">

$ echo $mypath:h                    
/usr/local/src /usr/src/bar.cc
$ echo $mypath:gh
/usr/local/src /usr/src

</programlisting></entry>
                </row>

                <row>
                  <!-- <entry><command>:t</command></entry> -->

                  <entrytbl cols="1">
                    <tbody>
                      <row>
                        <entry><command>:t</command>&nbsp;&nbsp;
                        <command>:gt</command></entry>
                      </row>
                    </tbody>
                  </entrytbl>

                  <entrytbl cols="1">
                    <tbody>
                      <row>
                        <entry>interprète le contenu de la variable comme un
                        nom de fichier <productname>Unix</productname> et en
                        donne la fin, <abbrev>i.e.</abbrev> la partie après le
                        dernier /</entry>
                      </row>
                    </tbody>
                  </entrytbl>

                  <entry><programlisting width="36">

$ echo $mypath:t                    
foo.c /usr/src/bar.cc
$ echo $mypath:gt
foo.c bar.cc

</programlisting></entry>
                </row>

                <row>
                  <!--  <entry><command>:r</command></entry> -->

                  <entrytbl cols="1">
                    <tbody>
                      <row>
                        <entry><command>:r</command>&nbsp;&nbsp;
                        <command>:gr</command></entry>
                      </row>
                    </tbody>
                  </entrytbl>

                  <entry>supprime l'extension en fin de variable.</entry>

                  <entry><programlisting width="36">

$ echo $mypath:r
/usr/local/src/foo /usr/src/bar.cc  
$ echo $mypath:gr
/usr/local/src/foo /usr/src/bar

</programlisting></entry>
                </row>

                <row>
                  <!-- <entry><command>:e</command></entry> -->

                  <entrytbl cols="1">
                    <tbody>
                      <row>
                        <entry><command>:e</command>&nbsp;&nbsp;
                        <command>:ge</command></entry>
                      </row>
                    </tbody>
                  </entrytbl>

                  <entry>donne l'extension correspondant à la fin de
                  variable.</entry>

                  <entry><programlisting width="36">

$ echo $mypath:e                    
c /usr/src/bar.cc
$ echo $mypath:ge
c cc

</programlisting></entry>
                </row>

                <row>
                  <!-- <entry><command>:q</command></entry> -->

                  <entrytbl cols="1">
                    <tbody>
                      <row>
                        <entry><command>:q</command>&nbsp;&nbsp;
                        <command>:gq</command></entry>
                      </row>
                    </tbody>
                  </entrytbl>

                  <entry>quote la variable pour éviter tout mécanisme de
                  substitution.</entry>

                  <entry></entry>
                </row>

                <row>
                  <!-- <entry><command>:x</command></entry> -->

                  <entrytbl cols="1">
                    <tbody>
                      <row>
                        <entry><command>:x</command>&nbsp;&nbsp;
                        <command>:gx</command></entry>
                      </row>
                    </tbody>
                  </entrytbl>

                  <entrytbl cols="1">
                    <tbody>
                      <row>
                        <entry align="left">idem précédent, mais cassure en
                        mots sur les caractères : blanc, espace et nouvelle
                        ligne.</entry>
                      </row>
                    </tbody>
                  </entrytbl>

                  <entry></entry>
                </row>
              </tbody>
            </tgroup>
          </table></para>
      </formalpara>

      <formalpara>
        <title>Mécanismes de substitution</title>

        <para><table>
            <title>Clé de substitution</title>

            <tgroup cols="2">
              <colspec align="left" colname="c1" colnum="1" colwidth="1*+1" />

              <colspec align="left" colname="c2" colnum="2" colwidth="3*+1" />

              <thead valign="middle">
                <row>
                  <entry align="center">Clé</entry>

                  <entry align="center">Sémantique</entry>
                </row>
              </thead>

              <tbody>
                <row>
                  <entry><varname>$?&lt;name&gt;</varname> =
                  <varname>${?&lt;name&gt;}</varname></entry>

                  <entry>Renvoit 1 si la variable est définie, 0
                  sinon.</entry>
                </row>

                <row>
                  <entry><varname>$?0</varname></entry>

                  <entry>Renvoit 1 si $0 est définie, 0 sinon.</entry>
                </row>

                <row>
                  <entry><varname>$$</varname></entry>

                  <entry>Substituée par le pid du
                  <foreignphrase>shell</foreignphrase> parent.</entry>
                </row>

                <row>
                  <entry><varname>$!</varname></entry>

                  <entry>Substituée par le pid du dernier processus asynchrone
                  lancé par le <foreignphrase>shell</foreignphrase>
                  parent.</entry>
                </row>

                <row>
                  <entry><varname>$&lt;</varname></entry>

                  <entry>Substituée par une ligne de l'entrée
                  standard.</entry>
                </row>
              </tbody>
            </tgroup>
          </table> <programlisting width="80">

$ set v = toto
$ echo ${?v}   # renvoit 1 puisque la variable v est définie        
1
$ echo $u
u: Undefined variable.
$ echo ${?u}   # moyen commode pour savoir si une variable est définie          
0 

</programlisting></para>
      </formalpara>
    </sect2>

    <sect2>
      <title>Paramètres du shell</title>

      <para>Le <foreignphrase>shell</foreignphrase> définit pour chaque
      commande un certain nombre de paramètres <quote>automatiques</quote>.
      <table>
          <title>Opérateurs de comparaison</title>

          <tgroup cols="2">
            <colspec align="left" colname="c1" colnum="1" colwidth="1*+1" />

            <colspec align="left" colname="c2" colnum="2" colwidth="3*+1" />

            <thead valign="middle">
              <row>
                <entry align="center">Paramètre(s)</entry>

                <entry align="center">Utilisation</entry>
              </row>
            </thead>

            <tbody>
              <row>
                <entry align="left"><varname>$0</varname></entry>

                <entry align="justify">nom de la commande ou du script
                invoqué.</entry>
              </row>

              <row>
                <entry><varname>$1</varname>, <varname>$2</varname> ..
                <varname>$n</varname>&nbsp;&nbsp; <varname>${1}</varname>,
                <varname>${2}</varname> .. <varname>${n}</varname></entry>

                <entry>encore équivalent à <varname>$argv[1]</varname>,
                <varname>$argv[2]</varname>, .. <varname>$argv[n]</varname>
                &nbsp;&nbsp; valeurs des paramètres positionnels passés à la
                commande ou au script.</entry>
              </row>

              <row>
                <entry align="left"><varname>$*</varname> =
                <varname>$argv[*]</varname> &nbsp;&nbsp;&nbsp; =
                <varname>${argv[*]}</varname></entry>

                <entry align="left">ensemble des paramètres, sauf $0.</entry>
              </row>

              <row>
                <entry><varname>$#</varname> = <varname>$#argv</varname>
                &nbsp;&nbsp;&nbsp;&nbsp; = <varname>${#argv}</varname></entry>

                <entry align="left" colname="c2">nombre de paramètres
                effectifs, $0 non compris.</entry>
              </row>
            </tbody>
          </tgroup>
        </table> <programlisting width="80">
<emphasis>CODE :</emphasis>

#!/bin/csh
# ~/bin/testparm.sh

echo 'je suis le script, $0 = ' $0

if ( ${#argv} &gt; 0 ) then
    echo ' évoqué avec $# (= $#argv = ${#argv}) = ' ${#argv}  ' arguments sur la
 ligne de commande'
    echo 'Voici les paramètres : $* (= $argv[*] = ${argv[*]}) = ' ${argv[*]}
    set i = 1
    foreach param ( $argv[*] ) 
       écho "paramètres ($i) :  $param"
       @ i++
    end
else
    echo ' pas d arguments, nb arg $# (= $#argv = ${#argv}) = ' ${#argv}
endif

# fin du script


<emphasis>EXEMPLE :</emphasis>

$ ./testparam.sh toto titi tutu 147
je suis le script, $0 =  ./testparam.sh
 évoqué avec $# (= $#argv = ${#argv}) =  4  arguments sur la ligne de commande  
Voici les paramètres : $* (= $argv[*]) =  toto titi tutu 147
paramètre (1) :  toto
paramètre (2) :  titi
paramètre (3) :  tutu
paramètre (4) :  147
$
$ ./testparam.sh
je suis le script, $0 =  ./testparam.sh
 pas d arguments, nb arg $# (= $#argv = ${#argv}) =  0
$

</programlisting></para>
    </sect2>

    <sect2>
      <title>Lecture sur l'entrée standard</title>

      <para>Elle se fait en utilisant la variable spéciale
      <varname>$&lt;</varname> <programlisting width="80">
<emphasis>CODE :</emphasis>

#!/bin/csh
# ~/bin/testread.sh                                                             

echo -n " Votre réponse (o, n) ? "
set rep = $&lt;

if ( $rep == o ) then 
   echo "réponse oui"
else
   echo autre réponse : $rep
endif


<emphasis>EXEMPLE :</emphasis>

$ ./testread.sh
Votre réponse (o, n) ? yes
autre réponse : yes

$ ./testread.sh
 Votre réponse (o, n) ? o
réponse oui

</programlisting></para>
    </sect2>

    <sect2>
      <title>Expressions conditionnelles</title>

      <para><emphasis role="bold">Règles</emphasis> : <itemizedlist>
          <listitem>
            <para>Les expressions utilisent les mêmes opérateurs que le
            langage <emphasis>C</emphasis> (sémantique identique (sauf marque
            : (¢), <abbrev>c.f.</abbrev> <quote><xref
            linkend="expr" /></quote>)). On retrouve les instructions
            <command>if</command>, <command>while</command>,
            <command>@</command> et <command>exit</command>,</para>
          </listitem>

          <listitem>
            <para>Les chaines numériques commençant par un 0 sont interprétées
            comme des valeurs en base octale,</para>
          </listitem>

          <listitem>
            <para>Le résultat de toute expression est une chaîne représentant
            un nombre décimal.</para>
          </listitem>

          <listitem>
            <para>La valeur 0 s'interprète en contexte logique comme la valeur
            <quote>faux</quote>, toutes les autres ont la valeur
            <quote>vrai</quote>.</para>
          </listitem>
        </itemizedlist> <table id="expr">
          <title>Opérateurs de comparaison</title>

          <!-- one of (graphic mediaobject tgroup) -->

          <tgroup cols="2">
            <colspec align="left" colname="c1" colnum="1" colwidth="1*+1" />

            <colspec align="left" colname="c2" colnum="2" colwidth="3*+1" />

            <thead valign="middle">
              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="center">Opérateur</entry>

                <entry align="center">Sémantique</entry>
              </row>
            </thead>

            <tbody>
              <!-- FILE -->

              <row>
                <entry nameend="c2" namest="c1"><emphasis role="bold">O P E R
                A T E U R S &nbsp;&nbsp; D E &nbsp;&nbsp; F I C H I E R
                S</emphasis></entry>
              </row>

              <row>
                <entry><command><option>-d</option>
                &lt;filename&gt;</command></entry>

                <entry>(¢) est vraie si le fichier désigné par
                <emphasis>&lt;filename&gt;</emphasis> est un
                répertoire.</entry>
              </row>

              <row>
                <entry><command><option>-e</option>
                &lt;filename&gt;</command></entry>

                <entry>(¢) est vraie si le fichier désigné par
                <emphasis>&lt;filename&gt;</emphasis> existe.</entry>
              </row>

              <row>
                <entry><command><option>-f</option>
                &lt;filename&gt;</command></entry>

                <entry>(¢) est vraie si le fichier désigné par
                <emphasis>&lt;filename&gt;</emphasis> est un fichier
                régulier.</entry>
              </row>

              <row>
                <entry><command><option>-o</option>
                &lt;filename&gt;</command></entry>

                <entry>(¢) est vraie si le fichier désigné par
                <emphasis>&lt;filename&gt;</emphasis> est propriété de
                l'utilisateur.</entry>
              </row>

              <row>
                <entry><command><option>-r</option>
                &lt;filename&gt;</command></entry>

                <entry>(¢) est vraie si le fichier désigné par
                <emphasis>&lt;filename&gt;</emphasis> est un fichier
                accessible en lecture.</entry>
              </row>

              <row>
                <entry><command><option>-w</option>
                &lt;filename&gt;</command></entry>

                <entry>(¢) est vraie si le fichier désigné par
                <emphasis>&lt;filename&gt;</emphasis> est un fichier
                accessible en écriture.</entry>
              </row>

              <row>
                <entry><command><option>-x</option>
                &lt;filename&gt;</command></entry>

                <entry>(¢) est vraie si le fichier désigné par
                <emphasis>&lt;filename&gt;</emphasis> est un fichier
                exécutable.</entry>
              </row>

              <row>
                <entry><command><option>-z</option>
                &lt;filename&gt;</command></entry>

                <entry>(¢) est vraie si le fichier désigné par
                <emphasis>&lt;filename&gt;</emphasis> est de taille
                nulle.</entry>
              </row>

              <row>
                <entry><command><option>-b</option>
                &lt;filename&gt;</command></entry>

                <entry>[<emphasis
                role="bold"><emphasis>tcsh</emphasis></emphasis>] (¢) est
                vraie si le fichier désigné par
                <emphasis>&lt;filename&gt;</emphasis> est un fichier spécial
                en mode bloc.</entry>
              </row>

              <row>
                <entry><command><option>-c</option>
                &lt;filename&gt;</command></entry>

                <entry>[<emphasis
                role="bold"><emphasis>tcsh</emphasis></emphasis>] (¢) est
                vraie si le fichier désigné par
                <emphasis>&lt;filename&gt;</emphasis> est un fichier spécial
                en mode caractère.</entry>
              </row>

              <row>
                <entry><command><option>-l</option>
                &lt;filename&gt;</command></entry>

                <entry>[<emphasis
                role="bold"><emphasis>tcsh</emphasis></emphasis>] (¢) est
                vraie si le fichier désigné par
                <emphasis>&lt;filename&gt;</emphasis> est un lien
                symbolique.</entry>
              </row>

              <row>
                <entry><command><option>-p</option>
                &lt;filename&gt;</command></entry>

                <entry>[<emphasis
                role="bold"><emphasis>tcsh</emphasis></emphasis>] (¢) est
                vraie si le fichier désigné par
                <emphasis>&lt;filename&gt;</emphasis> est un <emphasis>tube
                nommés</emphasis> (<emphasis>FIFO</emphasis>).</entry>
              </row>

              <row>
                <entry><command><option>-S</option>
                &lt;filename&gt;</command></entry>

                <entry>[<emphasis
                role="bold"><emphasis>tcsh</emphasis></emphasis>] (¢)est vraie
                si le fichier désigné par
                <emphasis>&lt;filename&gt;</emphasis> est un
                <emphasis>socket</emphasis>.</entry>
              </row>

              <!-- STRING -->

              <row>
                <entry nameend="c2" namest="c1"><emphasis role="bold">C O M P
                A R A I S O N &nbsp;&nbsp; D E &nbsp;&nbsp; C H A I N E
                S</emphasis></entry>
              </row>

              <row>
                <entry><command>&lt;str1&gt; <option>==</option>
                &lt;str2&gt;</command></entry>

                <entry>est vraie si <emphasis>&lt;str1&gt;</emphasis> est
                égale à <emphasis>&lt;str2&gt;</emphasis>.</entry>
              </row>

              <row>
                <entry><command>&lt;str1&gt; <option>!=</option>
                &lt;str2&gt;</command></entry>

                <entry>est vraie si <emphasis>&lt;str1&gt;</emphasis> est
                différente de <emphasis>&lt;str2&gt;</emphasis>.</entry>
              </row>

              <row>
                <entry><command>&lt;str1&gt; <option>=~</option>
                &lt;str2&gt;</command></entry>

                <entry>(¢) est vraie si le motif
                <emphasis>&lt;str2&gt;</emphasis> (<foreignphrase>right hand
                side</foreignphrase>) correspond au motif
                <emphasis>&lt;str1&gt;</emphasis>.</entry>
              </row>

              <row>
                <entry><command>&lt;str1&gt; <option>!~</option>
                &lt;str2&gt;</command></entry>

                <entry>(¢) est vraie si le motif
                <emphasis>&lt;str2&gt;</emphasis> (<foreignphrase>right hand
                side</foreignphrase>) ne correspond pas au motif
                <emphasis>&lt;str1&gt;</emphasis>.</entry>
              </row>

              <!-- ENTIER -->

              <row>
                <entry nameend="c2" namest="c1"><emphasis role="bold">C O M P
                A R A I S O N &nbsp;&nbsp; D ' E N T I E R
                S</emphasis></entry>
              </row>

              <row>
                <entry><command>&lt;int1&gt; <option>&gt;=</option>
                &lt;int2&gt;</command></entry>

                <entry>est vraie si <emphasis>&lt;int1&gt;</emphasis> est
                supérieur ou égal à <emphasis>&lt;int2&gt;</emphasis>.</entry>
              </row>

              <row>
                <entry><command>&lt;int1&gt; <option>&gt;</option>
                &lt;int2&gt;</command></entry>

                <entry>est vraie si <emphasis>&lt;int1&gt;</emphasis> est
                strictement supérieur à
                <emphasis>&lt;int2&gt;</emphasis>.</entry>
              </row>

              <row>
                <entry><command>&lt;int1&gt; <option>&lt;=</option>
                &lt;int2&gt;</command></entry>

                <entry>est vraie si <emphasis>&lt;int1&gt;</emphasis> est
                inférieur ou égal à <emphasis>&lt;int2&gt;</emphasis>.</entry>
              </row>

              <row>
                <entry><command>&lt;int1&gt; <option>&lt;</option>
                &lt;int2&gt;</command></entry>

                <entry>est vraie si <emphasis>&lt;int1&gt;</emphasis> est
                strictement inférieur à
                <emphasis>&lt;int2&gt;</emphasis>.</entry>
              </row>

              <!-- COMBINAISON D'EXPR -->

              <row>
                <entry nameend="c2" namest="c1"><emphasis role="bold">C O M B
                I N A I S O N &nbsp;&nbsp; D ' E X P R E S S I O N
                S</emphasis></entry>
              </row>

              <row>
                <entry><command> ( &lt;expr&gt; ) </command></entry>

                <entry>est vraie si <emphasis>&lt;expr&gt;</emphasis> est
                vraie.</entry>
              </row>

              <row>
                <entry><command> <option>!</option> &lt;expr&gt;
                </command></entry>

                <entry>est vraie si <emphasis>&lt;expr&gt;</emphasis> est
                fausse.</entry>
              </row>

              <row>
                <entry><command> &lt;expr1&gt; <option>&amp;&amp;</option>
                &lt;expr2&gt; </command></entry>

                <entry>est vraie si <emphasis>&lt;expr1&gt;</emphasis> et
                <emphasis>&lt;expr2&gt;</emphasis> sont simultanément
                vraies.</entry>
              </row>

              <row>
                <entry><command> &lt;expr1&gt; <option>||</option>
                &lt;expr2&gt; </command></entry>

                <entry>est vraie si <emphasis>&lt;expr1&gt;</emphasis> ou
                <emphasis>&lt;expr2&gt;</emphasis> est/sont vraie(s).</entry>
              </row>
            </tbody>
          </tgroup>
        </table> <table>
          <title>Opérateurs (par ordre décroissant de priorité)</title>

          <tgroup cols="2">
            <colspec align="left" colname="c1" colnum="1" colwidth="1*+1" />

            <colspec align="left" colname="c2" colnum="2" colwidth="3*+1" />

            <thead valign="middle">
              <row>
                <entry align="center">Opérateurs</entry>

                <entry align="center">Sémantique</entry>
              </row>
            </thead>

            <tbody>
              <row>
                <entry><command>( &nbsp; )</command></entry>

                <entry>regroupement</entry>
              </row>

              <row>
                <entry><command>~</command></entry>

                <entry>complément bit à bit</entry>
              </row>

              <row>
                <entry><command>!</command></entry>

                <entry>négation logique.</entry>
              </row>

              <row>
                <entry><command>*</command> &nbsp; <command>/</command> &nbsp;
                <command>%</command></entry>

                <entry>multiplication, division, modulo</entry>
              </row>

              <row>
                <entry><command>+</command> &nbsp;
                <command>-</command></entry>

                <entry>addition, soustraction</entry>
              </row>

              <row>
                <entry><command>&lt;&lt;</command> &nbsp;
                <command>&gt;&gt;</command></entry>

                <entry>décalage à gauche, décalage à droite</entry>
              </row>

              <row>
                <entry><command>&lt;=</command> &nbsp; <command>&lt;</command>
                &nbsp; <command>&gt;=</command> &nbsp;
                <command>&gt;</command></entry>

                <entry>opérateurs relationnels</entry>
              </row>

              <row>
                <entry><command>==</command> &nbsp; <command>!=</command>
                &nbsp; <command>=~</command> &nbsp;
                <command>!~</command></entry>

                <entry>opérateurs de comparaisons de chaînes</entry>
              </row>

              <row>
                <entry><command>&amp;</command></entry>

                <entry><quote>et</quote> bit à bit</entry>
              </row>

              <row>
                <entry><command>^</command></entry>

                <entry><quote>ou exclusif</quote> bit à bit</entry>
              </row>

              <row>
                <entry><command>|</command></entry>

                <entry><quote>ou</quote> (inclusif) bit à bit</entry>
              </row>

              <row>
                <entry><command>&amp;&amp;</command></entry>

                <entry><quote>et</quote> logique</entry>
              </row>

              <row>
                <entry><command>||</command></entry>

                <entry><quote>ou</quote> logique</entry>
              </row>
            </tbody>
          </tgroup>
        </table> La commande interne <command>@</command> permet de réaliser
      des opérations arithmétiques sur des valeurs ou variables entières,
      attention à respecter l'espace entre le symbole @ et la variable.
      <programlisting width="80">

$ set v = 3
$ set u = 8
$ set p = 5
$ @ x = $v + $u * $p   # attention à la priorité des opérateurs                 
$ echo $x
43
$ @ x = ( $v + $u ) * $p
55

$ @ q = $u / $p        # division entière
$ @ r = $u % $p
$ echo quotient = $q et reste = $r
quotient = 1 et reste = 3

$ @ v++                # incrémentation d'une unité
$ echo $v
4

$ @ v += 2             # incrémentation de deux unités
$ echo $v
6

$ @ u /= 2             # @ u = u / 2
$ echo $u
4

$ @ u = ( $u &lt;&lt;  3 )   # décalage à gauche de 3 bits, ce qui revient à une x 8  
$ echo $u
32

$ @ v = (( $v + 4 ) &gt;&gt; 2 ) # 10 décaler de 2 bits à droite, soit 10 / 4 = 2
$ echo $v
2


</programlisting></para>
    </sect2>
  </sect1>

  <!-- 4e partie -->

  <sect1>
    <title>Les apports de TCsh</title>

    <sect2>
      <title><foreignphrase>Completion</foreignphrase> étendue</title>

      <para>Sous <emphasis>tcsh</emphasis> le mécanisme de
      <foreignphrase>completion</foreignphrase> des noms a été amélioré. Ce
      <foreignphrase>shell</foreignphrase> peut compléter les noms des
      fichiers, des commandes et des variables. De plus la
      <foreignphrase>completion</foreignphrase> des noms de fichiers est
      programmable !</para>

      <para>La <foreignphrase>completion</foreignphrase> est déclenchable par
      la touche &lt;<command>TAB</command>&gt;, bien que par compatibilité
      ascendante avec <command><emphasis>csh</emphasis></command>, la touche
      &lt;<command>ESC</command>&gt; reste opérationnelle.</para>

      <formalpara>
        <title>Contexte de variables :</title>

        <para>Il faut utiliser le préfixe <command>$</command> (il change le
        contexte de la <foreignphrase>completion</foreignphrase>) :
        <programlisting width="80">

$ set varia_1=10                                                                
$ echo $var&lt;TAB&gt;
$ echo $varia_1 &lt;ENTREE&gt;
10

</programlisting></para>
      </formalpara>

      <!-- 
    <para> &todo; </para>
-->
    </sect2>

    <sect2>
      <title><command>bindkey</command></title>

      <para>Cette commande permet l'édition des commandes en ligne dans un
      buffer au moyen des contrôles associés aux éditeurs classiques
      d'<emphasis>Unix</emphasis>, à savoir <command>vi</command> ou
      <command>emacs</command>. Utilisée seule, elle retourne la liste des
      associations clés/commandes.</para>

      <para>Le positionnement par défaut est souvent le mode
      <command>emacs</command>, il est déterminé à la compilation. La variable
      <command>version</command> permet de connaître la version de la commande
      ainsi que les options de compilation. Dans l'exemple suivant, l'absence
      de la clé <command>vi</command>, permet d'affirmer que le mode par
      défaut est <command>emacs</command>. <programlisting width="80">

$ echo $version
tcsh 6.12.00 (Astron) 2002-07-23 (i386-intel-FreeBSD) options 8b,nls,dl,al,kan,s
m,rh,color,dspm,filec

</programlisting></para>

      <para>Cette commande permet aussi de commuter entre le mode
      <command>vi</command> et le mode <command>emacs</command>.
      <programlisting width="80">

$ bindkey -e   # mode emacs                                                     
$ bindkey -v   # mode vi

</programlisting></para>

      <para>Dans le tableau suivant, nous présentons un sous-ensemble des
      commandes d'édition : <table>
          <title>Quelques couples clé/commande en mode
          <command>emacs</command></title>

          <!-- one of (graphic mediaobject tgroup) -->

          <tgroup align="left" cols="2">
            <colspec colname="c1" colnum="1" colwidth="1*+1" />

            <colspec colname="c2" colnum="2" colwidth="3*+1" />

            <thead>
              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="center">Clé</entry>

                <entry align="center">Commande</entry>
              </row>
            </thead>

            <tbody>
              <row>
                <!-- one of (entrytbl entry) -->

                <entry align="center">^A</entry>

                <entry>Positionne le curseur en début de ligne</entry>
              </row>

              <row>
                <entry align="center">^B</entry>

                <entry>Recule horizontalement le curseur d'un
                caractère</entry>
              </row>

              <row>
                <entry align="center">^E</entry>

                <entry>Postionne le curseur en fin de ligne</entry>
              </row>

              <row>
                <entry align="center">^L</entry>

                <entry>Efface l'ecran</entry>
              </row>

              <row>
                <entry align="center">^K</entry>

                <entry>Coupe tous les caractères à la droite du
                curseur</entry>
              </row>

              <row>
                <entry align="center">^T</entry>

                <entry>Transposition de caractères</entry>
              </row>

              <row>
                <entry align="center">^M</entry>

                <entry>Nouvelle ligne</entry>
              </row>

              <row>
                <entry align="center">^U</entry>

                <entry>Efface toute la ligne</entry>
              </row>

              <row>
                <entry align="center">^C</entry>

                <entry>Signal d'interruption</entry>
              </row>

              <row>
                <entry align="center">^Z</entry>

                <entry>Signal de suspension</entry>
              </row>

              <row>
                <entry align="center">Backspace</entry>

                <entry>Efface le premier caractère situé à gauche du
                curseur</entry>
              </row>

              <row>
                <entry align="center">Flèche gauche</entry>

                <entry>Déplacement d'un caractère à gauche du curseur</entry>
              </row>

              <row>
                <entry align="center">Flèche droite</entry>

                <entry>Déplacement d'un caractère situé à droite du
                curseur</entry>
              </row>

              <row>
                <entry align="center">Flèche haut</entry>

                <entry>Remonte dans l'historique des commandes (vers les
                commandes les plus anciennes)</entry>
              </row>

              <row>
                <entry align="center">Flèche bas</entry>

                <entry>Descend dans l'historique des commandes</entry>
              </row>
            </tbody>
          </tgroup>
        </table></para>
    </sect2>

    <sect2>
      <title><foreignphrase>Spelling Correction</foreignphrase></title>

      <para>Ce mécanisme est déclenché en postionnant la variable (interne)
      <emphasis>tcsh</emphasis> <varname>correct</varname> (valeurs possibles
      <emphasis>cmd</emphasis> ou <emphasis>all</emphasis>) : <programlisting
      width="80">

$ set correct = cmd
$ lzss test.csh                          # ooops typo !

CORRECT&gt;less test.csh  (y|n|e|a)? yes    # frappe de la touche y ou &lt;ESPACE&gt;    
#!/bin/csh                               # lecture et affichage du fichier

echo '\nJe suis le programme $0   : ' $0
...

</programlisting></para>
    </sect2>
  </sect1>

  <!-- VERSION ASR DEBUT -->

  <!-- 4e PARTIE : EXOS -->

  <sect1>
    <title>Exercices</title>

    <simplesect>
      <title>Exercice - Mécanisme d'évaluation (1)</title>

      <para>Soit les affectations suivantes : <programlisting width="80">

$ set x=date                                                                        
$ set y=foobar 

</programlisting></para>

      <para>Tester les commandes suivantes et expliquer dans chaque cas le
      résultat obtenu. <programlisting width="80">

$ echo $x ; echo $y ; echo $z                                                   

$ echo "$x" ; echo "$y" ; echo "$z"

$ echo '$x' ; echo '$y' ; echo '$z'

$ echo `$x` ; echo `$y` ; echo `$z` 

$ $x ; $y ; $z

$ "$x" ; "$y" ; "$z"

$ '$x' ; '$y' ; '$z'

$ `$x` ;  `$y` ; `$z` 

$ $y=`$x` 

$ echo $foobar

</programlisting></para>
    </simplesect>

    <simplesect>
      <title>Exercice - Mécanisme d'évaluation (2)</title>

      <para>Tester les commandes suivantes et expliquer dans chaque cas le
      résultat obtenu. <programlisting width="80">

$ echo pwd                                                                      

$ `echo pwd`

$ 'echo pwd'

$ "echo pwd"

$ echo echo pwd

$ echo `echo pwd`

$ echo 'echo pwd'

$ echo "echo pwd"

$ echo '`echo pwd`'

$ echo '`echo pwd`'

</programlisting></para>
    </simplesect>

    <simplesect>
      <title>Exercice - Modification de l'environnement d'un processus,
      incidence sur le/les fils</title>

      <para>Dans un terminal, sous le <foreignphrase>shell</foreignphrase>
      courant définir deux variables (<varname>var1</varname> et
      <varname>var2</varname>) et modifier quelques variables d'environnement.
      Afficher l'environnement ainsi modifié.</para>

      <para>Dans ce même terminal, empiler un nouveau shell
      (<command>/bin/tcsh</command>). Quelle sont les valeurs de
      <varname>var1</varname> et <varname>var2</varname>, des variables
      d'environnement ? Définir une variable <varname>var3</varname>.</para>

      <para>Quitter ce <foreignphrase>shell</foreignphrase> et revenir à
      l'environnement initial (<command>exit</command>). Examiner son
      environnement, que vaut <varname>var3</varname> ? Conclure.</para>

      <para>Exporter maintenant la variable <varname>var1</varname>, empiler
      un nouveau <foreignphrase>shell</foreignphrase>. Examiner son
      environnment. Modifier ensuite <varname>var1</varname>. Définir la
      variable <varname>var2</varname>. Quitter ce
      <foreignphrase>shell</foreignphrase>, pour revenir à celui de départ.
      Quelles sont les valeurs de <varname>var1</varname> et
      <varname>var2</varname> ?</para>

      <para>Et si avant de quitter ce <foreignphrase>shell</foreignphrase>
      empilé, vous aviez exporté la variable <varname>var2</varname>,
      qu'auriez-vous obtenu ?</para>
    </simplesect>

    <simplesect>
      <title>Exercice - Exécution asynchrone concurrente de processus</title>

      <para>Exécuter la commande suivante dans un premier terminal, et dans un
      second ouvert pour l'occasion, lister les processus en cours d'exécution
      (se limiter aux seuls processus du terminal <quote>générateur</quote>),
      observer leur filiation, le nombre de processus : <programlisting
      width="80">

$ ( ls -la /usr/bin/ ; sleep 5 ; echo "5 - OK" ; last ) &amp; \                     
( cat /etc/passwd ; sleep 7 ; echo "7 - OK" ; cat /etc/group ) &amp; ps aux

</programlisting> Observer l'entrelacement des résulats de ces
      commandes.</para>

      <para>La séquence <foreignphrase>backslash</foreignphrase>
      (<abbrev>i.e.</abbrev> \), suivit de la touche &lt;Entrée&gt; indique au
      <foreignphrase>shell</foreignphrase> une continuation de la commande sur
      la ligne suivante. Que fait la commande <command>sleep</command>
      ?</para>
    </simplesect>

    <simplesect>
      <title>Exercice - Manipulation de jobs (1)</title>

      <para>Lancer la commande suivante : <computeroutput>find / -type d
      -print</computeroutput>, laquelle recherche tous les objets de type
      répertoire dans toute l'arborescence. La recherche se fait de manière
      récursive et comme l'arborescence est grande, l'exécution est
      <emphasis>un peu longue</emphasis>. On est bloqué tant que le processus
      exécutant le <command>find</command> n'est pas terminé. Il vous est
      demandé de : <orderedlist numeration="lowerroman" spacing="compact">
          <listitem>
            <para>suspendre (ou stopper) le processus.</para>
          </listitem>

          <listitem>
            <para>de le relancer en arrière-plan</para>
          </listitem>

          <listitem>
            <para>de le ramener au premier plan</para>
          </listitem>

          <listitem>
            <para>de le terminer.</para>
          </listitem>
        </orderedlist> Est-il possible de <quote>tuer</quote> des processus ne
      vous appartenant pas ? Tester-le.</para>

      <para>Si vous n'êtes pas assez rapide ou bien si la commande s'exécute
      trop rapidement, ouvrir un nouveau terminal et refaire le travail
      demandé.</para>
    </simplesect>

    <simplesect>
      <title>Exercice - Manipulation de jobs (2)</title>

      <para>Reprendre l'exemple de la commande <command>find</command>, de la
      section <quote><xref linkend="sect_redirection_comm" /></quote>, mais
      limiter la recherche au répertoire <filename>/etc</filename>.
      <orderedlist numeration="lowerroman" spacing="compact">
          <listitem>
            <para>Rediriger uniquement la sortie d'erreur dans le fichier
            (<filename>ferr</filename>) ;</para>
          </listitem>

          <listitem>
            <para>Rediriger uniquement la sortie standard dans un fichier
            (<filename>fout</filename>) ;</para>
          </listitem>

          <listitem>
            <para>Multiplexer les sorties standard et d'erreur dans le même
            fichier (<filename>fouterr</filename>) ;</para>
          </listitem>

          <listitem>
            <para>Rediriger (démultiplexer) la sortie standard et la sortie
            d'erreur dans les fichiers respectifs (<filename>fout</filename>
            et <filename>ferr</filename>).</para>
          </listitem>
        </orderedlist></para>
    </simplesect>
  </sect1>

  <!-- VERSION ASR FIN -->

  <!-- =================================================================== -->

  <bibliography>
    <title>Références</title>

    <bibliodiv>
      <biblioentry>
        <abbrev>0</abbrev>

        <author>
          <surname>OpenBSD man pages</surname>
        </author>

        <title>csh</title>

        <edition><ulink url="http://www.openbsd.org/cgi-bin/man.cgi">man
        csh</ulink></edition>

        <date>Janvier 1994</date>
      </biblioentry>

      <biblioentry>
        <abbrev>1</abbrev>

        <author>
          <firstname>Heuer</firstname>

          <surname>Konrad</surname>
        </author>

        <title>Making friends with C-Shell and TC-shell, Part I</title>

        <edition><ulink
        url="http://ezine.daemonnews.org/200112/"></ulink></edition>

        <date>Décembre 2001</date>
      </biblioentry>

      <biblioentry>
        <abbrev>2</abbrev>

        <author>
          <firstname>Heuer</firstname>

          <surname>Konrad</surname>
        </author>

        <title>Making friends with C-Shell and TC-shell, Part II</title>

        <edition><ulink
        url="http://ezine.daemonnews.org/200201/"></ulink></edition>

        <date>Janvier 2002</date>
      </biblioentry>

      <biblioentry>
        <abbrev>3</abbrev>

        <author>
          <firstname>Heuer</firstname>

          <surname>Konrad</surname>
        </author>

        <title>Making friends with C-Shell and TC-shell, Part III</title>

        <edition><ulink
        url="http://ezine.daemonnews.org/200202/"></ulink></edition>

        <date>Février 2002</date>
      </biblioentry>

      <biblioentry>
        <abbrev>4</abbrev>

        <author>
          <surname>University of Hawaii at Manoa - College of
          Engineering</surname>
        </author>

        <title>The C Shell tutorial</title>

        <edition><ulink url="http://www.eng.hawaii.edu/Tutor/csh.html">csh
        tutorial</ulink></edition>

        <date>2001</date>
      </biblioentry>

      <biblioentry>
        <abbrev>5</abbrev>

        <author>
          <firstname>Pélissier</firstname>

          <surname>Christian</surname>
        </author>

        <title>Unix</title>

        <subtitle>Utilisation, Administration, Réseau Internet</subtitle>

        <pagenums>Chap 9, pp 163-176</pagenums>

        <edition>HERMES</edition>

        <date>1992, 1995, 1996, 1998</date>

        <isbn>isdn : 2-86601-707-2</isbn>
      </biblioentry>
    </bibliodiv>
  </bibliography>
</article>
