tcsh : un shell C étendu
tcsh n'est sans doute pas le shell le plus utilisé au monde mais il est parmi ceux qui obtiennent les faveurs des utilisateurs avertis. Ce shell est une version étendue du shell C classique. Il ajoute de nombreuses fonctionnalités dont la complétion des commandes, des fichiers et des arguments, mais il implémente également l'édition de ligne comme la plupart des shells modernes.

Le gros avantage de tsch face à des monstres de fonctionnalité comme zsh est sans nul doute la rapidité. Ceci n'est certes pas visible sur une machine dernier cri mais devrait ravir les utilisateurs de configurations modestes soucieux de leur ligne... de commandes.

Configuration de base
La dernière version de tsch en date est la 6.10.00. En principe, celle-ci devrait être disponible sous forme de package pour votre distribution. Dans le cas extrême où vous ne trouvez pas de binaire packagé, il est toujours possible de recompiler et d'installer tsch sur votre système.

Les fichiers de configuration utilisés par tcsh sont lus dans l'ordre suivant :

/etc/csh.cshrc et /etc/csh.login
~/.tcshrc (ou ~/.cshrc)
~/.history (ou la valeur définie dans ~/.tcshrc)
~/.login
~/.cshdirs (ou la valeur définie par $dirsfile)

Le fichier de configuration important dans le cas d'un login interactif d'un utilisateur est, bien sûr, le ~/.tcshrc. C'est à celui-ci que nous consacrerons le plus d'attention.

La première variable que nous définirons concernera le style du echo intégré au shell :

set echo_style = both

Les valeurs possibles sont les suivantes :
-
bsd, dans ce cas, la commande echo provoquera un saut de ligne sauf si echo est suivi par l'option n ;
-
sysv, permet de reconnaître les séquences échappées () ;
-
both, permet d'utiliser bsd et sysv ;
-
none, désactive ces fonctionnalités.

Ici, inutile de jouer la carte de la distinction ; tous les systèmes GNU/Linux reconnaissent l'option n et les caractères d'échappement.

Nous pouvons nous intéresser aux fonctionnalités de base concernant la complétion de commandes et de noms de fichiers. Nous définissons trois variables :

set addsuffix
set autolist
set matchbeep = nomatch

addsuffix permet de suffixer les noms de commande complétés par un espace et les noms de répertoire par /. Cela étant très pratique, nous serions idiots de nous en passer. autolist permet l'affichage de propositions si une commande, un nom de fichier ou de répertoire peut être complété de plusieurs manières. Là encore, il s'agit d'un fonctionnement classique.

Enfin, matchbeep définit l'utilisation du signal sonore (bell). Les valeurs possibles sont :

never, rendra la complétion complètement muette ;
nomatch, signalera l'absence complète de correspondance dans la complétion ;
notunique, signale le fait qu'il y ait une correspondance exacte mais également d'autres correspondances plus longues ;
ambiguous, déclenchera le signal dans le cas de plusieurs correspondances (ceci est la valeur par défaut en l'absence de matchbeep).

Afin ne nous protéger contre les mauvaises manipulations, nous pouvons définir d'autres variables :

set noclobber nous protègera en restreignant l'utilisation des caractères de redirection > et >>. L'utilisation de > sera protégée contre l'écrasement de fichiers existants et >> ne fonctionnera, au contraire, que si le fichier est présent. Ceci n'est pas d'une très grande utilité ; les utilisateurs de systèmes Unix sont éduqués pour être responsable de leurs actes ;)

set rmstar

Voici une sécurité supplémentaire. Une confirmation sera demandée (par le shell) dans le cas de l'utilisation du méta-caractère * pour une suppression (rm).

set symlinks ignore

Nous définissons là le fonctionnement courant de n'importe quel shell. A savoir, lorsque l'utilisateur entre dans un répertoire étant un lien symbolique puis utilise cd .. pour en ressortir, il se retrouve à l'emplacement précédent. En initialisant cette variable avec chase au lieu d'ignore, tcsh est capable de vous placer dans le chemin entièrement résolu. Dernière valeur, expand, permet de résoudre le lien symbolique sur la ligne de commande et ce, pour n'importe quelle saisie. Bien que cela puisse être utile, préférons rester dans le cadre normal en utilisant ignore.

Dernier point de la configuration classique : l'historique des commandes. Ici, deux variables suffisent pour obtenir le résultat escompté :

set histdup = all
set savehist = (100 merge)

La première variable permet d'éviter la duplication de lignes dans l'historique. Les autres valeurs possibles sont prev, qui limite l'insertion d'une commande dans l'historique si celle-ci est identique à la précédente, ou erase, qui supprimera une ligne identique déjà existante.
Le fichier contenant l'historique des commandes est par défaut ~/.history, mais il est possible de spécifier un autre fichier avec :

set histfile = nom_du_fichier

La seconde variable définit que nous souhaitons conserver l'historique en quittant le shell. La valeur numérique correspond au nombre de lignes enregistrées de l'historique courant vers la sauvegarde. Le paramètre merge précise que nous souhaitons conserver le précédent historique enregistré et le fusionner avec le nouveau.

set notify

Enfin, ce dernier paramètre de notre configuration de base demande au shell de nous garder informés du fonctionnement des process qu'il aura lancés. Si nous prenons l'exemple d'une command lancée en fond (avec &) et que celle-ci se termine, le shell nous le signalera par un message.


Complétion
De base, n'importe quel shell moderne est en mesure de proposer une sélection de commandes, de répertoires et de noms de fichiers à l'aide de la touche de complétion <TAB> ou ^D. tcsh va plus loin dans ce domaine en permettant la complétion d'autres éléments comme les options de commande ou encore le filtrage des noms de fichiers ou de répertoires.

Par souci d'organisation, il est préférable de placer les différentes lignes définissant les complétions dans un fichier indépendant. En temps normal, ces lignes sont placées dans
~/.tsch mais nous choisirons ici de créer un nouveau fichier (par exemple ~/.tcsh_comp) que nous sourcerons depuis ~/.tsch en y ajoutant la ligne :

source ~/.tsch_comp

Nous pourrons alors nous en donner à c ur joie dans le nouveau fichier.
La complétion de tcsh fonctionne à n'importe quel endroit de la ligne de commande éditée. Vous pouvez donc faire usage de la touche magique (
<TAB>) à n'importe quel emplacement sur la ligne. Notez également la possibilité d'utiliser la séquence ^D afin d'obtenir la liste des propositions sans procéder à la complétion.

Un certain nombre de variables en relation avec la complétion peuvent être définies :
- fignore permet de définir des motifs de noms de fichiers à ignorer dans la complétion. Notez que les noms ignorés de cette manière apparaîtront cependant avec la ^D. Dans bien des cas, les copies de secours (suffixe ~) et les fichiers objets (.o) générés lors d'une compilation ne sont que rarement utilisés. Nous pouvons donc les ignorer pour la complétion de noms de fichiers avec set fignore = (.o ~). Notez que fignore ne s'applique pas dans le cas où la complétion ne propose qu'une seule réponse.

- complete peut prendre une valeur enhance. Dans ce cas, les points (.) et les tirets haut (-) et bas (_) sont considérés comme des séparateurs. Voici un exemple, imaginez que vous ayez une dizaine de fichiers dans un répertoire. Parmi eux se trouvent les fichiers titi.asc, tutu.aps et trois.alpha. En initialisant complete avec enhance, nous pouvons obtenir une complétion automatique en tapant simplement :

$ ls t.a<TAB>

Nous obtiendrons nos trois fichiers car tous commencent par la lettre t et leur suffixe par la lettre a. Le point est considéré comme un séparateur de mots et la complétion agit sur chaque mot de manière distincte. Nous avons cependant remarqué que cette variable définit dans le fichier de configuration, la manipulation ne fonctionnait pas. En revanche, si set complete = enhance est saisi sur la ligne de commande, la complétion avec les séparateurs fonctionne.

Nous pouvons maintenant nous pencher sur les lignes de définition pour la complétion. Une telle ligne est composée de la manière suivante :

complete commande mot/motif/liste:selection/suffixe(s)/

Certains de ces paramètres sont optionnels. Voici quelques explications sur ces paramètres :
-
mot définit quel mot par rapport au mot courant doit être complété. Les valeurs possibles sont :
         c pour le mot courant, où motif doit correspondre avec le début du mot sur la ligne de commande. Le motif est ignoré pour la complétion.
         C, idem mais le motif est ajouté.
         n, ici le motif doit correspondre avec le mot précédant le mot courant.
         N, idem mais la correspondance est faite sur deux mots avant le mot courant.
         p, le motif est une plage de valeurs correspondant à la position par rapport au mot courant.

-
motif est le motif de complétion (nous verrons des exemples plus loin dans l'article).

-
liste permet de choisir le type de complétion ou plus exactement l'objet qui sera susceptible de compléter la commande (la liste où chercher). Les valeurs sont :
         a pour les alias
         b pour les commandes de l'éditeur de ligne
         c pour les commandes internes ou externes
         C pour les commandes externes
         d pour les répertoires
         D pour les répertoires (mais la complétion s'applique uniquement à un préfixe fourni par l'utilisateur)
         e pour les variables d'environnement
         f pour les noms de fichiers
         F pour les noms de fichiers (avec fourniture d'un préfixe)
         g pour les noms de groupes
         j pour les tâches (jobs)
         l pour les limites (corezise, etc.)
         n pour... rien
         s pour les variable du shell
         S pour les signaux
         t pour les fichiers plein-texte
         T idem mais avec le préfixe
         v pour toutes les variables
         u pour les noms d'utilisateurs

Il existe ensuite trois autres valeurs possibles qui sont plus génériques :
         $var qui utilisera tous les mots présents dans la variable $var.
         (...) pour les mots de la liste donnée.
         `...` pour les mots provenant de la sortie d'une commande.

-
selection est optionnel et permet de ne proposer dans la complétion que les valeurs de liste qui correspondent avec selection.

-
suffixe est également optionnel et permet d'ajouter un caractère arbitraire après la complétion. Notez que le slash (/) est automatiquement ajouté pour un répertoire et un espace pour les autres mots en l'absence de ce paramètre.

Je pense que quelques exemples ne seront pas inutiles pour clarifier tout cela. Commençons avec la classique complétion de la commande cd qui ne doit, en principe, proposer que des noms de répertoires. Voici la ligne correspondante pour votre fichier de complétion :

complete cd 'p/*/d/'

Remarquez d'en fin de compte ce n'est pas si complexe ;) Nous utilisons la commande complete sur cd avec une complétion dépendante de n'importe quelle (*) position (o) et ne proposons que les répertoires (d). Résultat, il nous suffit de taper cd<TAB> sur la ligne de commande pour que tcsh ne nous propose que les répertoires pour la complétion.

Nous bien comprendre le principe de position, voici un second exemple tout aussi viable pour la commande cd :

complete cd 'p/1/d/'

Ici, la correspondance ne s'appliquera qu'au premier mot. Ceci ne change rien pour la commande cd puisque celle-ci ne prend en compte qu'un seul argument, qui est un nom de répertoire.

Ceci peut être appliqué à n'importe quelle position :

complete -mu* 'p/0/(mutt muttDB)/'

Cet exemple plus complexe concerne la complétion du premier mot (en position 0). Il doit exister sur votre système un grand nombre de commandes dont le nom débute avec mu. Ici les commandes qui nous intéressent sont mutt et muttDB. Nous précisons alors une complétion sur le premier mot : parmi toutes les commandes en position 0 et commençant par mu, nous ne proposerons que celles dans la liste fournie (mutt muttDB).

Dès lors, si nous tapons
mu<TAB>, le shell nous proposera uniquement les deux mises en paramètres. Notez la présence du tiret (-) qui permet d'appliquer cette complétion qu'avec les commandes ambiguës.

Voici à présent un exemple un peu plus complexe. Celui-ci démontre la possibilité de compléter une commande avec les informations fournies par un programme :

complete kill 'p/*/`ps | awk print$1`/'

Ici, la complétion portera sur un mot à n'importe quel emplacement. En effet, la commande kill permet d'envoyer un signal à plusieurs processus en mémoire. Pour obtenir des propositions pour la complétion, nous demandons tout simplement à la commande ps de nous fournir la liste des processus.

Cette liste n'est pas directement utilisable, nous n'avons besoin que des ID et non des autres informations retournées par ps. Nous filtrons donc tout cela avec une ligne de awk (seul le premier mot de chaque ligne est intéressant pour la commande kill).

Le résultat obtenu par une simple ligne comme celle-ci est fantastique. Il nous suffit de taper kill<TAB> pour envoyer un signal à un des processus en cours et ce, sans risquer une éventuelle faute de frappe.
Bien sûr, cet exemple est sans doute mal choisi puisque qu'un

$ kill `pidof kkchose`

ferait parfaitement l'affaire.

Evidemment, dans de nombreux cas, il n'est pas nécessaire de pousser aussi loin la configuration. Pour la majorité des commandes, une sélection sur le type de fichier est amplement suffisante. Si nous prenons le cas de la commande mplayer (player vidéo performant), nous n'aurons qu'à ajouter :

complete mplayer 'p/*/f:*.avi,mpg,mpeg,asf/'

Ceci est applicable à n'importe quelles applications pour utilisables qu'avec des fichiers spécifiques (citons par exemple latex, xv, links ou encore dpkg).

Finissons cette liste d'exemples avec le cas d'une utilisation de la complétion options :

complete gpg 'c/--/(version verify)/'par
'p/2/f:*.asc,sign,gpg/'

Comme vous pouvez le constater, nous spécifions deux complétions. La première complétera l'utilisation d'option débutant par -- et nous proposerons --version ou --verify. Ensuite, pour le mot en position 2 (le troisième), nous estimons que le seul choix possible concerne un fichier de signature. Enfin, nous arrêtons là les spécifications, les complétions qui suivront porteront que tous les fichier du répertoire courant. Attention, cet exemple n'est ni viable, ni complet (loin de là). Il illustre simplement la manière de proposer plusieurs complétions.

Nous terminerons ici cet article. Vous devrez, après avoir choisi tcsh comme shell, confectionner vos règles de complétion en fonction de vos besoins et des applications que vous utilisez. La seule source de documentation est la manpage de tcsh, mais vous trouverez certainement des informations utiles en faisant une petite recherche dans les archive de newsgroups.

Copyright (c) Linux Magazine France
Permission vous est donnée de distribuer des copies exactes de cette page tant que cette note de permission et le copyright apparaissent clairement.