Aller au contenu

Administration Unix - CM séance 04

5. Configuration du shell bash

5.1. Les alias

Un alias est un raccourci, qui permet de mémoriser une commande avec éventuellement des arguments.

📎  La commande alias

Les alias sont géré par la commande interne alias :

$ alias                  # affiche tous les alias
$ alias NOM              # affiche la définition de l'alias NOM
$ alias NOM=VALEUR       # définit l'alias

Exemple :

$ ls                     # affiche le catalogue en monochrome
$ alias ls='ls --color'  # on définit un alias
$ alias ls               # vérification
alias ls='ls --color'
$ ls                     # affiche le catalogue en couleur

Dans une ligne de commande avec des arguments, bash remplace juste la commande par l'alias ; par exemple, avec l'exemple précédent :

$ ls -la /tmp

sera remplacé par

$ ls --color -la /tmp

On peut préciser qu'on veut utiliser la commande originale en préfixant avec \ :

$ \ls                    # affiche le catalogue en monochrome

ou encore en donnant son chemin

$ /bin/ls                # idem en monochrome

On peut détruire des alias avec

$ unalias NOM...

ou encore supprimer tous les alias

$ unalias -a

Ordre de recherche pour bash :

  1. fonctions (vues prochainement)
  2. alias
  3. commandes internes (builtins)
  4. fichiers exécutables, dans l'ordre de $PATH

Attention, conflits possibles avec les mots réservés (for do done if then else ...)

🔭  La commande type

La commande interne type permet de dire à quoi correspond une commande :

$ type ls
ls est un alias vers « ls --color »
$ unalias ls
$ type ls
ls est haché (/bin/ls)

L'option -a affiche les possibilités dans l'ordre :

$ type -a echo
echo est une primitive du shell
echo est /bin/echo
$ alias echo='echo -n "Abra" ; echo'
$ echo cadabra !
Abracadabra !
$ type -a echo
echo est un alias vers « echo -n "Abra" ; echo »
echo est une primitive du shell
echo est /bin/echo
$ unalias echo

Important : les alias appartiennent au shell courant.
⟶ dans un sous-shell, ou dans un autre shell, les alias ne sont pas conservés.

$ alias boo='echo -n "Bouh ! Il est " ; date +"%H:%M"' 
$ boo
Bouh ! Il est 08:45
$ bash
$ boo
boo : commande introuvable

On peut rendre les alias permanents avec le fichier .basrc, cf plus loin.

5.2. Configuration du prompt

L'affichage du prompt est paramétrable via les variables suivantes :

  • PS1   prompt courant ('$', 'user@machine:répertoire $', etc)
  • PS2   prompt pour une ligne secondaire (défaut '> ')
  • PS3   prompt pour un choix avec select (défaut '#? ')
  • PS4   prompt en mode trace (défaut '+ ')

Exemples :

$ PS1=">>> "            # on change le prompt PS1
>>>                     # nouveau prompt

>>> PS2="... "
>>> echo bonjour \      # '\' en fin de ligne signifie que la ligne continue
... et au revoir        # le prompt PS2 est affiché
bonjour et au revoir
>>> 

>>> PS3="?? "
>>> select note in do ré mi ; do echo "Je joue la note $note" ; done
1) do                   # select affiche un menu puis demande un entier
2) ré
3) mi
?? 2                    # le prompt PS3 est affiché, l'utilisateur tape '2'
Je joue la note ré
?? ^C                   # la saisie recommence, ^C pour interrompre
>>> 

>>> foo=bar
>>> echo $foo
bar
>>> set -x              # active le mode trace
>>> echo $foo
+ echo bar              # chaque ligne est affichée avant exécution
bar
>>> PS4='trace: '
+ PS4='trace: '
>>> echo $foo
trace: echo bar         # le prompt PS4 a bien été changé
bar
>>> set +x              # désactive le mode trace
trace: set +x
>>> echo $foo
bar

Avant chaque affichage, le contenu des variables PS est interprété par le shell, qui effectue certaines substitutions :

  • \d   la date
  • \D{format}   la date avec un format, cf man date, FORMAT
  • \u   le nom de l'utilisateur.
  • \H   le hostname (= nom de la machine)
  • \h   le hostname, jusqu'au premier caractère "."
  • \w   le répertoire de travail courant (PWD)
  • \W   le basename du répertoire de travail courant.
  • \!   le numéro de la ligne de commande dans l'historique.
  • \$   Si l'id utilisateur est 0, affiche un #, sinon, affiche un $.
  • \e   un caractère d'échappement, par exemple pour la couleur.

etc, cf man bash : PROMPTING (ou INVITES si le man est en français).

Exemple :

>>> PS1='\u@\h:\w$ '
thiel@plaet:~$ 

thiel@plaet:~$ PS1='\u@\h:\w [\!] $ '
thiel@plaet:~ [2055] $

thiel@plaet:~ [2055] $ PS1='[\!] \u@\h:\w $ '
[2056] thiel@plaet:~ $

[2056] thiel@plaet:~ $ PS1='\D{%A %e %b %H:%M:%S}\n\u@\h:\w $ '
vendredi 16 oct. 09:10:09
thiel@plaet:~ $ 

thiel@plaet:~ $ PS1='\e[0;31m\D{%A %e %b %H:%M:%S}\e[m\n\u@\h:\w $ '
vendredi 16 oct. 09:10:19          # cette ligne est en rouge
thiel@plaet:~ $ 

La portion : \e[0;31m...\e[m est une séquence d'échappement pour afficher le texte ... en couleur (31=rouge, 32=vert, ...) dans le terminal :

$ echo -e "\e[0;34mBonjour\e[m"
Bonjour                             # en bleu

Voir : https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit

5.3. Options du shell

Le comportement de bash peut être paramétré avec des options.

🔌  La commande shopt

La commande interne shopt permet de gérer de nombreuses options (help shopt, ref).

$ shopt                # affiche toutes les options et leur état on/off
$ shopt -s NOM...      # active chaque option
$ shopt -u NOM...      # désactive chaque option

Remarque : quand on tape shopt -s ou shopt -u + Tab , bash affiche la liste des options possibles.

Les options activées sont mémorisées dans la variable BASHOPTS, séparées par :

$ echo $BASHOPTS

Certaines options permettent de paramétrer le globbing, qui est l'expansion par bash des motifs de noms de fichiers (pattern glob) utilisant les caractères spéciaux *, ?, etc :

  • fichiers cachés :

    $ mkdir tmp ; cd tmp ; touch .foo bar
    $ ls
    bar
    $ ls *
    bar
    $ shopt -s dotglob
    $ ls
    bar
    $ ls *
    bar  .foo           # effet de dotglob : * expanse les fichiers cachés
    
  • motifs ne correspondant à aucun fichier :

    $ echo a*
    a*                      # aucun fichier ne commence par a
    $ shopt -s nullglob
    $ echo a*
                            # a lieu d'afficher le motif, affiche la chaîne vide
    $
    
  • motif incluant les sous-répertoires :

    $ mkdir -p bim/bam/boum                 # on crée des sous-répertoires
    $ echo *
    bar bim .foo
    $ echo **
    bar bim .foo
    $ shopt -s globstar
    $ echo **
    bar bim bim/bam bim/bam/boum .foo       # effet de globstar sur **
    

🔧  La commande set

La commande interne set permet de nombreux réglages (help set, ref).

En particulier, elle permet de configurer des nom-option avec set -o (ou encore shopt -o) :

$ set -o                # affiche les options
$ set -o NOM            # active l'option
$ set +o NOM            # désactive l'option

Option utile : écrasement des fichiers

$ touch toto            # crée le fichier toto

$ set -o noclobber      # interdit l'écrasement
$ echo > toto
bash: toto : impossible d'écraser le fichier existant

$ set +o noclobber      # autorise l'écrasement
$ echo > toto           # le fichier a été écrasé

5.4. Les fichiers de configuration

Lorsqu'on se connecte à un système Unix, le premier shell exécuté est un login shell (qui peut être un script).

Les login shells exécutent dans l'ordre :

  • le fichier d'initialisation générale /etc/profile ;

  • le fichier d'initialisation de l'utilisateur : le premier trouvé parmi ~/.bash_profile , ~/.bash_login , ~/.profile.

    En général, on utilise ~/.profile (héritage du Bourne shell).

Chaque fois qu'on ouvre un shell bash interactif non-login, il exécute dans l'ordre :

  • le fichier général de démarrage des shells interactifs /etc/bash.bashrc ;

  • le fichier de démarrage des shells interactifs de l'utilisateur ~/.bashc.

Tous les processus lancés par l'utilisateur après le login sont des processus descendants du login shell ; ils héritent donc des variables d'environnement mémorisées dans /etc/profile et ~/.profile.

Dans .profile, on mémorise donc

  • le umask :

    set umask 022
    
  • le PATH :

    PATH="~/bin:$PATH"
    
  • les variables d'environnement :

    export TEXINPUTS=".:~/MesStylesLatex:"
    

Les shells interactifs héritent des variables d'environnement et autres réglages du .profile ; ils ont en plus besoin de connaître les réglages pour la ligne de commande de /etc/bash.bashrc et ~/.bashrc.

Donc dans .bashrc on met :

  • les prompts PS1, ... :

    PS1='\u@\h:\w$ '
    PS2='... '
    
  • les alias :

    alias ls='ls --color'
    
  • les options :

    set -o noclobber
    

Remarque : lorsqu'on a modifié .bashrc, pour tester l'effet dans le même terminal il suffit de taper :

$ source ~/.bashrc

(source exécute les commandes du fichier dans le même processus).

Les scripts bash sont par définition non-interactifs ; par précaution, .bashrc peut commencer par une garde qui empêche qu'il soit exécuté par un shell non interactif :

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

signifie : "si la variable PS1 est vide alors sort immédiatement".

Cas particulier : lors d'une connexion ssh, on obtient un login shell interactif, donc .bashrc n'est pas exécuté !

$ ssh localhost         # connexion locale, pour tester
$ alias                 # aucun alias

Pour exécuter quand même .bashrc on peut mettre au début de .profile :

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        source "$HOME/.bashrc"
    fi
fi

On reviendra dans les prochains cours sur la syntaxe [...] && et if [...].