La ligne de commande

État : {a_reli}

Retour au document principal

Pré-requis

Objectifs

Présentation

La ligne de commande est un moyen simple d'interagir avec un ordinateur. Le shell interprète les commandes tapées au clavier. Le prompt, ou l'invite de commande, qui se termine par un $ ou un # pour l'administrateur, indique que le shell attend les commandes de l'utilisateur.

Le shell est également un langage de programmation qu'on peut utiliser pour lancer des tâches automatiquement. Les programmes shell sont appelés des scripts.

Shells les plus courants

Le Bourne shell

/bin/sh

Le "Bourne again" shell

/bin/bash

Le Korn shell

/bin/ksh

Le C shell

/bin/csh

Tom's C shell

/bin/tcsh

le programme du LPI se concentre essentiellement sur le Bash, puisque c'est l'un des shells les plus couramment utilisés.

Le shell interactif

Les commandes shell suivent généralement la syntaxe suivante :

commande [options] {paramètres}

Afficher du texte à l'écran

Le bash utilise la commande echo pour afficher du texte à l'écran :

echo “Voici une courte ligne.”

Chemins relatif et absolu

Le shell interprète le premier "mot" de toute chaîne de caractère donnée comme une commande. Si cette chaîne est un chemin relatif ou absolu vers un fichier exécutable, alors le programme est exécuté. Si ce premier mot n'est pas précédé de /, alors le shell recherchera dans les répertoires définis dans la variable PATH et tentera de lancer la première commande qui correspondra à la chaîne.

Par exemple, si la variable PATH contient les répertoires /bin et /usr/bin, alors le système ne trouvera pas la chaîne xeyes puisque xeyes se trouve dans /usr/X11R6/bin/xeyes. Dans ce cas, vous devez entrer le chemin absolu de la commande :

/usr/X11R6/bin/xeyes

Mais on peut également utiliser le chemin relatif. Par exemple, si l'utilisateur est dans le répertoire où se trouve le programme xeyes, il peut taper :

./xeyes

Variables

Les variables du shell sont équivalentes aux variables utilisées dans les langages de programmation. Les noms de variables ne doivent contenir que des caractères alphanumériques. Par exemple, CREDIT=300 assigne tout simplement la valeur 300 à la variable nommée CREDIT.

  1. initialiser une variable : Nom_Variable=valeur (sans espace !)

  2. appeler une variable : $Nom_Variable

CREDIT=300
echo $CREDIT

On peut supprimer la valeur d'une variable avec la commande unset.

export, set et env

Il y a deux types de variables : les variables locales et les variables globales (exportées).

Les variables locales ne sont accessibles que sur le shell actif. Les variables exportées ou globales sont accessibles à la fois par le shell actif et par tous les processus fils lancés à partir de ce shell.

Les commandes set et env listent les variables définies.

Les commandes set et env

set

Liste toutes les variables

env

Liste les variables exportées

Une variable globale est globale dans le sens où elle est accessible par tous les processus fils.

Variable locale

Variable locale

Parent

Fils

Parent

Fils

VAR=val

VAR=?

VAR=val

VAR=val

Exemple : exportez la variable CREDIT puis testez si elle est listée par set ou env.

export CREDIT
env | grep CREDIT

Lancez un nouveau shell (processus fils) (NdT : en tapant bash) et vérifiez que la variable CREDIT est accessible. Peut-on lancer n'importe quel SHELL et être sûr que la variable CREDIT est toujours déclarée ?

Liste de variables courantes pré-définies :

Variable pré-définie

Signification

DISPLAY

Utilisé par X pour identifié iù lancer une application cliente

HISTFILE

Chemin vers le fichier utilisateur .bash_history

HOME

Répertoire personnel de l'utilisateur

LOGNAME

Identifiant de connexion de l'utilisateur

PATH

Liste des répertoires utilisés par le shell pour exécuter des programmes quand une commande est entrée dans chemin

PWD

Répertoire de travail actuel

SHELL

Shell utilisé (bash dans la plupart des distributions Linux

TERM

 Émulation de terminal utilisée

Variables spéciales

Les variables suivantes sont relatives à la gestion des processus :

Variable

Signification

$!

PID du dernier processs fils

$$

PID du shell actif

$?

valeur de sortie de la dernière commande : 0 = succès, 1 sinon

Entrées, sorties et redirections

Les processus UNIX ouvrent trois descripteurs de fichiers standards (NdT : correspondant aux flux standards) qui permettent de traiter les entrées et sorties. Ces descripteurs standards peuvent être redéfinis pour chaque processus. Dans la plupart des cas, le descripteur stdin (entrée standard) est le clavier, et les deux descripteurs de sortie, stdout (sortie standard) et stderr (l'erreur standard), sont l'écran.

Un processus et ses 3 descripteurs de fichiers

STDIN < ------ PROCESSUS ---- >
                   |     ---- >>  STDOUT
                   |     ---- | 
                   |
                  2>
                STDERR

Valeurs numériques pour stdin, stdout et stderr

flux

Valeur numérique

stdin

0

stdout

1

stderr

2

Redirection de la sortie standard

programme > fichier

Les données vont de gauche à droite.

fdisk –l > partitions.txt  

Ceci lance fdisk et redirige la sortie vers le fichier partitions.txt. La sortie n'est pas visible a l'écran. Notez que le shell lit cette commande à partir de la droite : le fichier partitions.txt est d'abord créé s'il n'existait pas auparavant, écrasé dans le cas contraire car l'opérateur ">" est utilisé.

L'opérateur ">>" ajoute la sortie standard à un fichier.

Redirection de la sortie standard :

          ----  > ----
PROCESSUS ---- >> ---- FICHIER / PÉRIPHÉRIQUE
          ---- 1> ----

Redirection de l'entrée standard

programme < fichier

Dans ce cas, les données vont de droite à gauche. L'opérateur "<" ne peut être utilisé qu'avec stdin donc on ne peut pas l'utiliser avec les flux de sortie.

Si le fichier contient les instructions p, m et q (une instruction par ligne), alors dans l'exemple suivant fdisk affichera la table des partitions de /dev/hda, puis affichera l'aide puis quittera :

fdisk /dev/hda  < instructions 

Redirection de l'entrée standard :

PROCESSUS ---- <  ---- FICHIER / PÉRIPHÉRIQUE
          ---- 0< ----

Redirection de l'erreur standard

programme 2> fichier_erreur

stdin, stdout et stderr sont représentés respectivement par 0, 1 et 2. Cela nous permet de choisir le flux d'erreur standard :

find / 2> /dev/null

Redirection de l'erreur standard :

PROCESSUS ---- 2> ---- FICHIER / PÉRIPHÉRIQUE

Les tubes

programme1 | programme2

Les tubes sont représentés par l'opérateur "|". Les données vont de gauche à droite. La figure suivante indique comment la sortie standard su premier processus est redirigée vers l'entrée standard du second processus.

Redirection à partir d'un tube :

PROCESSUS1 (stdout) ---- | ---- (stdin) PROCESSUS2

Exemple :

cat /var/log/messages | less                       

Note : Les redirections de sortie multiples sont analysées de droite à gauche, ainsi les commandes suivantes ne sont pas équivalentes :

commande  2>&1  > fichier
commande  >fichier  2>&1

La commande tee

commande | tee FICHIER

La commande tee est utilisé après un tube et prend comme paramètre un nom de fichier. La sortie standard de la commande précédente est alors écrite dans le fichier (NdT : comme avec ">") mais tee laisse le flux vers la sortie standard. La sortie standard est dupliquée.

Méta-caractères et guillemets

Les méta-caractères ont un sens spécial pour le shell. Ils sont la plupart du temps utilisés comme jokers, pour correspondre à plusieurs noms de fichiers ou de répertoires en utilisant un minimum de lettres.

Les caractères d'entrée (<), de sortie (>) et le tube (|) sont également des caractères spéciaux ainsi que le dollar ($) utilisé pour les variables. Nous ne les listerons pas ici, mais notez que ces caractères sont rarement utilisés pour nommer des fichiers standards.

Caractères génériques ou jokers

ls  /usr/bin/b*

Liste tous les programmes commençant par "b".

ls  /usr/bin/?b*

Liste tous les programmes ayant un "b" pour seconde lettre.

ls  a[0-9]

liste tous les fichiers commençant par un "a" suivis d'un chiffre en seconde position.

ls  [!Aa]*

liste tous les fichiers qui ne commencent pas par un "a" ni par un "A"

ls  index.{htm,html}

Guillemets et caractères d'échappement

On peut annuler la signification des jokers en utilisant des caractères d'échappement, qui sont également des caractères génériques.

L'antislash (\), qu'on appelle le caractère d'échappement, annule le sens de tous les caractères génériques, en forçant le shell à les interpréter littéralement.

Les guillemets simples, ou apostrophes (' ') annule le sens de tous les caractères génériques sauf l'antislash.

Les guillemets (doubles) (" ") sont les guillemets faibles mais annulent la plupart des méta-caractères entourés à l'exception du tube (|), de l'antislash (\) et des variables ($var).

Les guillemets inversés ̀`

Les guillemets inversés exécutent la commande entourée. L'exemple suivant définit la variable TIME à partir de la commande date.

TIME="La date d'aujourd'hui est le `date +%a:%d:%b`”
echo $TIME
La date d'aujourd'hui est le mar.:06:juil.

Pour exécuter des commandes, on peut également utiliser $(). La commande sera exécutée et traitée comme une variable.

TIME=$(date)

L'historique des commandes

Pour voir la liste des commandes que vous avez tapé, vous pouvez utiliser la commande interne de bash history.

history
1 ls
2 grep   500 /etc/passwd

history liste les commandes en cache ainsi que celles sauvées dans ~/.bash_history. Lorsque que l'utilisateur quitte le shell, les commandes en cache sont inscrites dans ~/.bash_history.

Vous pouvez récupérer les commandes tapées en utilisant les flèches directionnelles (haut et bas) de votre clavier. Vous pouvez également utiliser des raccourcis emacs qui vous permettent d'exécuter et même de modifier ces lignes.

Raccourcis clavier Emacs pour l'historique des commandes :

Ctrl+p

Ligne précédente (équivalent à la flèche haute)

Ctrl+n

Ligne suivante (Next) (= flèche basse)

Ctrl+b

Aller au caractère précédent sur la ligne (Back) (= flèche gauche)

Ctrl+f

Aller au caractère suivant (Forward) (=flèche droite)

Ctrl+a

Aller au début de la ligne (= touche Orig)

Ctrl+e

Aller en fin de ligne (End) (= touche Fin)

Le point d'exclamation ! peut être utilisé pour relancer une commande.

Exemple :

!x                         lance la dernière commande de l'historique commençant par un "x"
!2                         lance la commande n°2 de l'historique
!-2                        lance l'avant dernière commande
!!                         lance la dernière commande
^chaine1^chaine2           lance la dernière commande en remplaçant chaine1 par chaine2

Autres commandes

alias

Vous pouvez créer des alias pour des commandes nécessitant beaucoup de paramètres. La syntaxe d'alias est :

alias monprog='commande [options]{paramètres}'

alias tout seul donne la liste des alias déjà définis.

Auto-complètement de commandes

En appuyant sur TAB, le shell complète les commandes que vous avez commencé à taper.

<< est une redirection de EOF (fin de fichier)

Par exemple

cat << stop

accepte des entrées jusqu'à ce que "stop" soit tapé.

Commandes en chaîne

commande1; commande2; commande3

Ces trois commandes sont exécutées en séquence sans se préoccuper du résultat de la commande précédente.

commande1 && commande2 &&  commande3

Chaque commande sera exécutée seulement si la commande précédente a réussi (code de sortie 0) (NdT : && est un ET logique).

commande1 || comande2 ||  commande3

La commande suivante sera lancée uniquement si la précédente a échoué (code de sortie différent de 0) (NdT : || est un OU logique).

La commande "exec"

exec est une commande interne du bash utilisée pour lancer d'autres commandes. Normalement, quand vous lancez une commande, un sous-processus est créé. Si vous utilisez la commande exec pour lancer le nouveau programme, il remplace le processus qui l'a lancé, c'est à dire le shell pour un script ou un shell interactif.

Quand la commande se termine, le contrôle n'est pas redonné au shell, mais retourne au processus qui avait lancé le shell.

echo $$
414

$ bash
$ echo $$
455

$ echo hello
hello
$ echo $$
455

$ exec echo hello
hello
$ echo $$
414

L'exemple précédent montre que le contrôle revient au second shell (processus 455) quand on lance la commande echo normalement, et au premier shell (processus 414) lorsqu'on utilise exec.

Les pages de manuel et la base whatis

Les pages de manuel sont organisées en sections, voici les principales sections que l'on devrait trouver dans une page de manuel :

NOM

Le nom du sujet du manuel suivi par une brève ligne de description

SYNOPSYS

La syntaxe de la commande

DESCRIPTION

Une description plus détaillée

OPTIONS

Un tour de toutes les options possibles et leur fonction

FICHIERS

Fichiers en lien avec le sujet (fichiers de configuration, etc.)

VOIR AUSSI

Autres pages de manuel en lien avec le sujet

La base de données whatis est un index de la description courte (section NOM) de l'ensemble des pages de manuel du système. Elle est actualisée par une tâche quotidienne cron. La base de données d'indexation whatis contient les deux champs suivants :

nom (clé)  –  description courte

La syntaxe de whatis est :

whatis <chaîne>

La sortie de la commande est la section NOM des pages de manuel pour lesquels la chaîne correspond à nom (clé).

La commande man permet également dinterroger la base de données d'indexation whatis en utilisant la syntaxe suivante :

man -k <chaîne>

Cette commande est équivalente à apropos. Contrairement à la commande whatis, ces commandes recherchent les correspondances dans les champs "nom" et "description courte". Si la chaîne correspond à un mot dans l'un des deux champs, la requête précédente renverra la section NOM entière.

Exemples : (les correspondances seront indiquées en gras quand je saurais le faire dans un espace de code...)

whatis lilo
lilo                 (8)  - Installer le chargeur de démarrage
lilo.conf [lilo]     (5)  - Fichier de configuration pour lilo

man -k  lilo
grubby               (8)  - Outil en ligne de commande pour configurer grub, lilo, et elilo
lilo                 (8)  - Installer le chargeur de démarrage
lilo.conf [lilo]     (5)  - Fichier de configuration pour lilo

La FHS recommande de placer les pages de manuel dans /usr/share/man. Cependant, on peut rechercher dans d'autres répertoires en utilisant la variable d'environnement MANPATH, que l'on configure dans /etc/man.config. Chaque répertoire est ensuite divisé en sous-répertoires correspondants aux sections du manuel. (NdT : il ne faut pas confondre les sections du manuel avec les sections d'une page de manuel que nous venons de voir).

Sections du manuel

Section 1

Programmes exécutables ou commandes de l'interpréteur de commandes (shell)

Section 2

Appels système, par exemple mkdir(2)

Section 3

Appels de bibliothèque, par exemple stdio(3)

Section 4

Fichiers spéciaux (situés généralement dans /dev)

Section 5

Formats des fichiers et conventions

Section 6

Jeux

Section 7

Divers

Section 8

Commandes de gestion du système

Section 9

Sous-programmes du noyau

Pour accéder à une section du manuel en particulier, il faut utiliser la syntaxe suivante :

man N command

Exemples :

man mkdir
man 2 mkdir

man crontab
man 5 crontab

Exercices et résumé

Questions de révision

Oui ou Non

  1. Si la variable PATH n'est pas correctement paramétrée, les utilisateurs ne peuvent lancer les programmes qu'en tapant leur chemin complet ou relatif : _

  2. On peut "tuber" la sortie standard STDOUT dans un fichier : _

  3. Une fois qu'un flux de donnée est passé dans un tube, ce flux n'est généralement plus visible sur STDOUT : _

  4. Toutes les commandes tapées dans le SHELL sont sauvegardées dans une base MySQL : _

Voir les réponses

Glossaire

Terme

Description

commandes chaînées

Plusieurs commandes tapées sur une seule ligne en utilisant des séparateurs? Suivant le séparateur, le shell lancera les commandes différemment

méta-caractère

Caractère qui n'est pas interprété littéralement par le shell parce qu'il a un sens

Expansion de nom de fichier (file globbing)

Terme utilisé pour le traitement de plusieurs fichiers avec l'utilisation des méta-caractères. Le nom vient du sous-programme glob sur les anciens shell UNIX qui était utilisé pour "développer" les caractères génériques donnés en ligne de commande

Redirection et tubes

Opérations qui manipulent les flux de données et les descripteurs de fichiers d'un processus. Une redirection implique un processus et un fichier, alors qu'un tube n'implique qu'un processus

stderr, stdin, stdout

Nom des descripteurs de fichiers disponibles pour chaque processus pour diriger les messages d'erreur, lire les flux d'entrée et écrire les sorties (hors erreurs)

caractères génériques

Les méta-caractères suivants utilisés pour correspondre à plus d'un caractère lorsqu'on travaille en ligne de commande : *, ?, "{}" ou "[]"

Commandes

Commande

Description (ou apropos)

alias

configure un alias pour une commande ou une séquence de commandes (voir man builtins ou help alias)

echo

Affiche du texte sur STDOUT

env

Liste les variables exportées (voir man builtins ou help env)

exec

Commande intégrée au shell utilisée pour lancer un programme mais en remplaçant le processus qui l'a appelé au lieu de créer un processus fils

export

exporte la valeur de la variable dans l'environnement pour les commandes exécutées par la suite (voir man builtins ou help export)

history

Affiche la liste de l'historique des commandes avec le numéro des lignes (voir man builtins ou help history)

tee

Lire depuis l'entrée standard et écrire sur la sortie standard et dans des fichiers

set

Liste toutes les variables dans l'environnement du shell courant (voir aussi man builtins et help set)

Travaux pratiques

Attention : Pour suivre les exercices, vous aurez besoin des commandes uuencode et uudecode. Vous les trouverez dans le paquet shareutils.

Stdin-stdout-stderr

Tapez les commandes suivantes et représentez si possible les séquences d'exécution sous la forme d'un diagramme équivalent à ceux utilisés dans ce chapitre.

ls /etc ; df > /tmp/out.1
(ls /etc ; df) > /tmp/out.2

find /etc -type f  2> /dev/null | sort 

tr [a-z] [A-Z] < /etc/passwd | sort > /tmp/passwd.tmp

cat /tmp/passwd.tmp | tr [A-Z] [a-z]

Ligne de commande

  1. Affichez tous les fichiers de /usr/X11R6/bin qui ne commencent pas par un x
    ls /usr/X11R6/bin/[!x]*
  2. La commande xterm a les options suivantes :

    -bg <couleur> couleur d'arrière plan

    -fg <couleur> couleur de premier plan

    -e <commande> exécute

    Créez un alias pour que la commande su ouvre un nouveau xterm en couleur et qu'il vous demande le mot de passe root.

    alias su=”xterm -bg orange -fg brown -e su - &”
    Où placeriez-vous cet alias pour le conserver sur le système ?
  3. Vous pouvez coder des fichiers (NdT : en fait, les convertir de binaires en texte) avec uuencode. Le fichier codé est redirigé vers stdout. Par exemple :

     uuencode /bin/bash super-shell > uufichier

    Cette commande convertit /bin/bash et produira un fichier nommé super-shell quand on utilisera uudecode sur le fichier codé uufichier.

    • Envoyez le fichier convertit uufichier par mail à un utilisateur local : vous pouvez soit utiliser uuencode et un tube | ou sauvegarder la sortie de uuencode dans un fichier uufichier, ce que l'on vient de faire, et utiliser un redirection de STDIN <.

    • Coupez uufchier en 5 :
    uuencode /bin/bash super-shell > uufichier
    split –b 150000 uufichier  fichier-coupe
    • Vous récupérerez des fichiers fichier-coupe.aa, fichier-coupe.ab, etc. Pour récupérer le fichier uufichier avec les données d'origine, faites :
    cat fichier-coupe.* > uufichier.new
    • Enfin, lancez uudecode sur ce fichier et regardez si ça fonctionne.
    uudecode   uufichier.new

    Cette commande devrait créer un fichier binaire nommé super-shell.

  4. Quel outil indique le chemin complet vers un exécutable en examinant la variable PATH ?

Variables

  1. Suivez les instructions suivantes :
    1. Assignez la valeur "virus" à la variable ALERT :
      ALERT=virus
    2. Vérifiez que la variable est définie en utilisant la commande set :

      set |grep ALERT
    3. La variable ALERT est-elle listée si vous utilisez env au lieu de set ? Ensuite, tapez "bash". Pouvez-vous accéder à votre variable ALERT ?

      bash
      echo $ALERT
    4. Notez la value de ALERT : (est-ce vide ?)
    5. Tapez exit ou (^D) pour retourner à votre session.

    6. Utilisez la commande export pour rendre la variable ALERT globale

      export ALERT
    7. Vérifiez que la variable est globale avec env.

      env | grep ALERT
    8. Lancez un nouveau shell bash et vérifiez que ALERT est définie dans ce shell :
      bash
      echo $ALERT
    9. Dans ce nouveau shell, modifiez la variable ALERT et exportez la :
      export ALERT=green
    10. Quittez ce shell. Quelle est la valeur de ALERT dans le shell d'origine ?

  2. À l'invite de commande, tapez les lignes suivantes :
    • CREDIT01=300;CREDIT02=400
      for VAR in CREDIT01 CREDIT02;do echo $VAR;done
      Remarquez que la variable VAR est référencée avec $VAR.
    • Relancez cette (deuxième) commande
    • Relancez cette (deuxième) commande en remplaçant CREDIT01 par $CREDIT01
  3. Modifiez la variable PS1 pour afficher le chemin complet de votre répertoire de travail.

    (Indication : la valeur de PS1 est [\u@ \W]\$, il vous suffit de remplacer \W par \w).

    • PS1='[\u@\h \w ]\$ '
    À quoi ressemble votre variable PS2 ?

Réponses aux questions

  1. Oui

  2. Non : STDOUT peut être redirigé vers un fichier

  3. Oui

  4. Non : les commandes sont en général stockées dans le fichier .bash_history du répertoire personnel de l'utilisateur.