\input{../_preamble}
\usepackage{menukeys}
\title{La ligne de commande}
\usepackage{units}
\usepackage{cleveref}
\usepackage{booktabs}
\usepackage{xltabular}
\usepackage{dingbat}
\usepackage{mdframed}
\mdfsetup{
  everyline,
  backgroundcolor=Lavender,
  hidealllines=true}
\usepackage{minted}
\setminted{
  bgcolor=Lavender,
  breaklines,
  breaksymbolright=\small\carriagereturn}
\setmintedinline{bgcolor=Lavender}
\usepackage{soul}
\makeindex[name=cmds, intoc, title={Liste des commandes et
  instructions}]

\begin{document}
\maketitle
\renewcommand{\contentsname}{Sommaire}
\tableofcontents

\chapter{Introduction}
\label{cha:introduction}
La \emph{ligne de commande} est avant tout une interface de
communication avec l'ordinateur, tout comme le sont les interfaces
graphiques auxquelles nous sommes habitués. Les interfaces graphiques
telles que le \emph{Bureau} sous Windows ou bien le \emph{Finder} sous
Mac OS sont en réalité comme une couche qui se superpose à la ligne de
commande, qui continue toujours à exister. Tout en masquant à
l'utilisateur la ligne de commande, elles traduisent néanmoins en
ligne de commande les opérations qui sont faites à l'aide de la
souris.

\paragraph{Exemple} Supposons que l'on veuille créer un
répertoire\footnote{C'est ansi que l'on appellera ce qui, sous Windows
  et Mac OS X, se nomme \emph{dossier}.} nommé \emph{travail} sur le
bureau, puis déplacer dans ce réperoire un fichier \emph{exemple.pdf}
que l'on vient de créer. À l'aide de la souris, on doit à peu près
effectuer les opérations suivantes:
\begin{enumerate}
\item faire un simple-clic du bouton droit de la souris, et choisir
  \menu{Dossier>Nouveau} dans le menu contextuel qui s'affiche;
\item dans la fenêtre qui s'affiche, saisir le nom du nouveau
  répertoire: \directory{travail}, puis cliquer sur le bouton
  \menu{Ok};
\item dernière opération, le déplacement du fichier
  \emph{exemple.pdf}: à l'aide du bouton gauche de la souris, faire
  glisser le fichier \emph{exemple.pdf} sur l'icône du répertoire
  \emph{travail}, et relâcher le bouton à ce moment.
\end{enumerate}
Pour réaliser les mêmes opérations à la ligne de commande, il aurait
fallu saisir les lignes suivantes:
\begin{enumerate}
\item création du dossier \emph{travail}:\\
  \index[cmds]{mkdir}\mintinline{text}{mkdir travail}
\item déplacement du fichier \emph{exemple.pdf} dans le dossier
  travail: \\
  \index[cmds]{mv}\mintinline{text}{mv exemple.pdf travail}
\end{enumerate}

\paragraph{Commentaire}
Il faut bien comprendre que le rôle de l'interface graphique n'est que
de traduire en lignes de commande les opérations que nous effectuons à
l'aide de la souris.  Reprenons à présent les deux dernières lignes de
commande pour mieux les comprendre:
\label{sec:commentaire}
\begin{enumerate}
\item dans \og\mintinline{text}{mkdir travail}\fg,
  \mintinline{text}{mkdir} est le nom d'un programme fait pour créer
  des répertoires; \mintinline{text}{mkdir} est en effet pour
  l'anglais \emph{make directory}. Quant à \emph{travail}, c'est tout
  simplement le nom du répertoire qu'on veut faire créer par le
  programme \mintinline{text}{mkdir}. La terminologie est la suivante:
  \mintinline{text}{mkdir} est le nom du programme, et
  \mintinline{text}{travail} est \emph{l'argument} que l'on passe à
  \mintinline{text}{mkdir}. Remarquez que l'on doit séparer l'argument
  du nom du programme par un espace. Pour terminer, on appuie sur la
  touche \emph{Entrée} pour commander l'exécution du programme.
\item dans \og\mintinline{text}{mv exemple.pdf travail}\fg, le nom du
  programme est \mintinline{text}{mv}, pour l'anglais \emph{move}; sa
  fonction est de déplacer des fichiers ou des répertoires. Comme son
  comportement, par rapport au programme \mintinline{text}{mkdir}, est
  différent, il accepte non pas un, mais deux arguments, chacun séparé
  par des espaces.  Observez de nouveau cette ligne de commande:
  tandis que le premier argument est le nom du fichier que l'on
  souhaite déplacer, le deuxième est le nom du répertoire de
  destination de ce fichier. Pour terminer, de la même manière que
  précédemment, on appuie sur la touche \emph{Entrée} pour commander
  le déplacement du fichier.
\end{enumerate}

Par cet exemple, on espère faire comprendre que si la syntaxe de la
ligne de commande peut paraître au premier abord difficile à
maîtriser, elle permet aussi, par sa sobriété même, de réaliser de
manière bien plus rapide et bien plus sûre les opérations que l'on
fait à l'aide de la souris. En voici les principales raisons:
\begin{itemize}
\item l'interface graphique est une surcouche logicielle; elle
  ralentit donc le système d'exploitation;
\item l'interface graphique, comme tout logiciel très complexe,
  comporte des erreurs de programmation. Ces \emph{bugs} peuvent aller
  jusqu'à bloquer com\-plè\-te\-ment le système d'exploitation;
\item à l'aide de l'interface graphique, on ne peut réaliser que les
  équivalents en ligne de commande qui ont été prévus par les
  programmeurs. En se privant de la ligne de commande, l'utilisateur
  se prive donc aussi de pouvoir réaliser les opérations qui ont été
  laissées de côté\footnote{C'est d'ailleurs ainsi, bien souvent, que
    les techniciens compétents dépannent les ordinateurs: en réalisant
    des commandes auxquelles l'interface graphique ne permet pas
    d'accéder.};
\item les lignes de commande peuvent être chaînées. Ainsi, par la
  simple ligne\\ \mintinline{text}{mkdir travail ; mv exemple.pdf
    travail} on peut réaliser en une seule fois toutes les opérations
  décrites pré\-cé\-dem\-ment. Il suffit, comme on le voit ici, de
  séparer les commandes par un point-virgule \mintinline{text}{;};
\item les lignes de commande acceptent des caractères appelés
  \emph{wildcards} à l'aide desquels on peut déclencher des opérations
  complexes, portant sur un très grand nombre de fichiers. Par
  exemple, le caractère \mintinline{text}{*} peut se substituer à
  n'importe quelle chaîne de caractères. Ainsi, pour reprendre ce qui
  précède, la commande\\ \mintinline{text}{mv *.pdf travail} aura pour
  effet de déplacer automatiquement tous les fichiers au format
  \verb|PDF| dans le répertoire \emph{travail}.
\end{itemize}

En d'autres termes, en passant par la ligne de commande, l'utilisateur
gagne en sécurité, en rapidité et en maîtrise du système ce qu'il perd
en ergonomie.

\section{Lancement du terminal}
\label{sec:lanc-du-term}
\begin{enumerate}
\item Sous Linux, il suffit de rechercher dans le menu une application
  nommée \emph{terminal} ou \emph{xterm} dans les \emph{outils
    système}.
\item Sous MacOs, l'application s'appelle \emph{terminal}. Elle donne
  accès à un nombre limité de commandes.
\item Sous Windows, il faut installer \emph{Cygwin} qui est disponible
  à l'adresse suivante: \url{https://cygwin.com}. Pour savoir comment
  faire:
  \begin{enumerate}
  \item \url{https://x.cygwin.com/docs/ug/setup.html} (en anglais)
  \item \url{http://migale.jouy.inra.fr/?q=fr/cygwin-install} (en
    français: dans ce document, il faut cependant sauter le point 10a)
  \end{enumerate}
\end{enumerate}

\chapter{Chemins d'accès et premières commandes}
\label{cha:les-chemins-dacces}
Les commandes portent le plus souvent sur des fichiers. Il est donc
important, pour savoir où se trouvent les fichiers que vous voulez
traiter, de connaître leur \emph{chemin d'accès}.

\section{Chemins relatifs et absolus}
\label{sec:chemins-relatifs-et}

\paragraph{Le home directory}
\label{sec:le-home-directory}
Dans les systèmes Linux, tous vos fichiers se trouvent dans votre
répertoire personnel, appelé le \emph{home directory}. Le nom de votre
répertoire personnel est le même que celui de l'identifiant sous
lequel vous vous êtes connecté. Par ailleurs, tous les répertoires des
différents utilisateurs sont situés à la racine du disque dur dans un
répertoire fondamental appelé \mintinline{text}{home}.

Supposons que votre identifiant soit \mintinline{text}{jacques}; votre
répertoire personnel sera donc:
\begin{minted}{text}
/home/jacques
\end{minted}
Obervez attentivement cette ligne. Vous remarquez que les noms des
répertoires sont séparés par le caractère \mintinline{text}{/}. Cela
veut dire que le signe \mintinline{text}{/} est utilisé pour indiquer
que l'on passe d'un répertoire donné à l'un de ses
sous-répertoires. Dans notre exemple, le répertoire
\mintinline{text}{jacques} est donc inclus dans le répertoire
\mintinline{text}{home}.

Remarquez encore le \mintinline{text}{/} qui est placé \emph{devant}
\mintinline{text}{home}: comme il n'est lui-même précédé de rien, il
indique que le répertoire \mintinline{text}{home} est placé \emph{à la
  racine du disque dur}.

\paragraph{Definition: chemins absolus, chemins relatifs}
\label{sec:chem-absol-chem}
Un chemin d'accès est dit \emph{absolu} quand il est donné à partir de
la racine du disque dur. Il est \emph{relatif} quand il est donné à
partir de tout autre endroit du disque dur. Soit par exemple le
répertoire \mintinline{text}{travail} créé par l'utilisateur
\mintinline{text}{jacques} dans son répertoire personnel. À partir de
ce répertoire, le chemin d'accès absolu sera
\begin{minted}{text}
/home/jacques/travail/
\end{minted}
tandis que le chemin relatif sera
\begin{minted}{text}
travail/
\end{minted}
Corrolaire: tout chemin d'accès absolu commence nécessairement par le
caractère \mintinline{text}{/}; quand ce n'est pas le cas, le chemin
d'accès est nécessairement relatif.

\paragraph{Conventions}
\label{sec:conventions}
Il existe un grand nombre de raccourcis ou de signes conventionnels
qui sont utilisés dans la ligne de commande. On en retiendra trois
pour le moment:
\begin{itemize}
\item \emph{home directory}: depuis tout endroit du disque dur, tout
  utilisateur peut accéder à son répertoire personnel par le raccourci
\begin{minted}{text}
~/
\end{minted}
  Ainsi, pour l'utilisateur \mintinline{text}{jacques},
  \mintinline{text}{~/travail} est l'équivalent de \\
  \mintinline{text}{/home/jacques/travail}.
\item \label{ref:parent-current}répertoire parent: quel que soit le
  répetoire dans lequel on se trouve, la séquence
  \mintinline{text}{..} désigne le \emph{répertoire parent},
  c'est-à-dire le répertoire qui le contient, ou bien qui est situé au
  niveau supérieur dans l'arborescence du disque dur. Par exemple, à
  partir du répertoire \mintinline{text}{/home/jacques/travail},
  \mintinline{text}{..}  désigne le répertoire
  \mintinline{text}{/home/jacques}.
\item répertoire courant: Quant au signe \og\mintinline{text}{.}\fg,
  il désigne tout simplement le répertoire dans lequel on se trouve.
\end{itemize}

\section{Premières commandes}
\label{sec:prem-comm}

\paragraph{pwd}
\label{sec:pwd}\index[cmds]{pwd|textbf}
Signifie \emph{print working directory}. Cette commande vous retourne
tout simplement le chemin d'accès absolu du répertoire dans lequel
vous vous trouvez. Très utile pour ne pas se perdre! Exemple:
\begin{minted}{text}
[robert@kiddo ~]$ pwd
/home/robert
\end{minted}
\begin{quoting}\footnotesize
  La séquence \mintinline{text}+[robert@kiddo ~]$+ est \emph{l'invite
    de commande} (anglais \emph{prompt}). C'est à la suite de cette
  invite que l'on entre les commandes. Nous y reviendrons. Observez
  pour le moment quelques unes des informations données par cette
  invite: l'utilisateur \mintinline{text}{robert} est connecté sur
  l'ordinateur \mintinline{text}{kiddo}; ensuite, le signe
  \mintinline{text}+~+ indique qu'il se trouve dans son \emph{home
    directory}, ce que retourne en effet la commande
  \mintinline{text}+pwd+ qui a été entrée ici. Enfin, le signe
  \mintinline{text}|$| indique que l'utilisateur
  \mintinline{text}|robert| n'est pas l'administrateur du système. En
  effet, le \emph{prompt} de l'administrateur du système, que l'on
  appelle \emph{root}, se termine par le signe
  \mintinline{text}|#|. Exemple:
\begin{minted}{text}
[root@kiddo ~]# pwd
/root
[root@kiddo ~]# 
\end{minted}
  Remarquez que le \emph{home directory} de l'utilisateur
  \mintinline{text}|root| n'est pas situé dans le répertoire
  \mintinline{text}|/home| qui est réservé aux utilisateurs non
  privilégiés.
\end{quoting}

\paragraph{mv}
\label{sec:mv}\index[cmds]{mv|textbf}
Signifie \emph{move}. Cette commande déplace les fichiers d'un endroit
vers un autre. La syntaxe est la suivante:
\begin{minted}[showspaces]{text}
mv <source> <destination>
\end{minted}
\begin{quoting}\footnotesize
  Par convention, le signe \verb*+ + marque l'espace.
\end{quoting}
Exemple: déplacement du fichier \mintinline{text}{trachiniennes.pdf}
dans le répertoire \mintinline{text}{travail}:
\begin{minted}{text}
[robert@kiddo ~]$ mv trachiniennes.pdf travail/
\end{minted}
Déplacement du fichier \mintinline{text}{trachiniennes.pdf} depuis le
répertoire \mintinline{text}{travail} vers le répertoire courant
(désigné par le raccourci \mintinline{text}|.|):
\begin{minted}{text}
[robert@kiddo ~]$ mv travail/trachiniennes.pdf .
\end{minted}
Déplacement avec indication des chemins absolus:
\begin{minted}{text}
[robert@kiddo ~]$ mv /home/robert/trachiniennes.pdf /home/robert/travail/
\end{minted}
Utilisation de raccourcis:
\begin{minted}{text}
[robert@kiddo ~]$ mv ~/trachiniennes.pdf ~/travail/
\end{minted}

\paragraph{cp}
\label{sec:cp}\index[cmds]{cp|textbf}
Signifie \emph{copy}. Cette commande copie des fichiers depuis un
endroit vers un autre. La syntaxe est comparable à celle de la
séquence \index[cmds]{mv}\mintinline{text}{mv}.
\begin{minted}[showspaces]{text}
cp <source> <destination>
\end{minted}
Exemple: copie du fichier \mintinline{text}{trachiniennes.pdf} dans le
répertoire \mintinline{text}{travail}:
\begin{minted}{text}
[robert@kiddo ~]$ cp trachiniennes.pdf travail/
\end{minted}
Copie du fichier \mintinline{text}{trachiniennes.pdf} depuis le
répertoire \mintinline{text}{travail} vers le répertoire courant
(désigné par le raccourci \mintinline{text}|.|):
\begin{minted}{text}
[robert@kiddo ~]$ cp travail/trachiniennes.pdf .
\end{minted}
Copie avec indication des chemins absolus:
\begin{minted}{text}
[robert@kiddo ~]$ cp /home/robert/trachiniennes.pdf /home/robert/travail/
\end{minted}
Utilisation de raccourcis:
\begin{minted}{text}
[robert@kiddo ~]$ cp ~/trachiniennes.pdf ~/travail/
\end{minted}

\paragraph{cd}
\label{sec:cd}\index[cmds]{cd|textbf}
Signifie \emph{change directory}. Permet de changer de répertoire
courant, par exemple pour travailler sur les fichiers d'un répertoire
différent de son \emph{home directory}. La syntaxe est la suivante:
\begin{minted}[showspaces]{text}
cd <chemin_d'accès_du_nouveau_répertoire>
\end{minted}

Exemple: changement vers le répertoire \mintinline{text}|/usr/bin|:
\begin{minted}{text}
[robert@kiddo ~]$ cd /usr/bin
[robert@kiddo /usr/bin]$ 
\end{minted}
\begin{quoting}\footnotesize
  Remarquez le changement de l'invite après l'exécution de la
  commande. L'invite nous donne l'indication du nouveau répertoire.
\end{quoting}
Confirmation par la commande \index[cmds]{pwd}\mintinline{text}{pwd}:
\begin{minted}{text}
[robert@kiddo /usr/bin]$ pwd
/usr/bin
[robert@kiddo /usr/bin]$ 
\end{minted}
\begin{quoting}\footnotesize
  NB: la commande \mintinline{text}{cd} seule fait revenir l'utilisateur
  directement dans son \emph{home directory}.
\end{quoting}

\paragraph{ls}
\label{sec:ls}\index[cmds]{ls|(textbf}
Signifie \emph{list}. Affiche à l'écran tous les fichiers et les
répertoires contenus dans un répertoire donné. Si on ne précise pas le
répertoire dont il faut lister les fichiers, la commande liste les
fichiers du répertoire courant. Exemple: on vérifie que le fichier
\mintinline{text}{trachiniennes.pdf} se trouve bien dans le répertoire
travail:
\begin{minted}{text}
[robert@kiddo ~]$ ls travail/
trachiniennes.pdf
\end{minted}
\begin{quoting}\footnotesize
  Comme on le voit, la commande retourne le nom du seul fichier qui se
  trouve dans le répertoire \mintinline{text}{travail}.\\
  La commande \mintinline{text}{ls} est l'une des plus importantes;
  elle admet de nombreuses options que nous détaillerons plus loin
  dans ce cours.
\end{quoting}

\section{Options}
\label{sec:options}
On a donné plus haut l'exemple de la commande \mintinline{text}|ls|
qui affiche à l'écran tous les fichiers contenus dans un répertoire
donné. Voici ce que retourne cette commande lancée sur notre dépôt
Git:
\begin{minted}{text}
[robert@kiddo courses]$ ls
fichiers ls-R makefile _preamble.tex README.md README.pdf README.tex texfiles
\end{minted}

Mais on peut souhaiter recueillir davantage d'informations. Par
exemple, dans la liste ci-dessus, on ne peut pas distinguer les
fichiers des répertoires. Heureusement, les commandes peuvent recevoir
des \emph{options}. Celles-ci sont de deux types:
\begin{enumerate}
\item Les options \enquote{longues}, qui sont préfixées par
  \mintinline{text}|--| et suivies de noms entiers.
\item Les options \enquote{courtes}, qui sont préfixées par
  \mintinline{text}|-| et suivies d'abréviations.
\end{enumerate}
Voici donc ce que donne la même commande \mintinline{text}|ls|, suivie
de l'option \mintinline{text}|-l| pour \enquote{use a \ul{l}ong
  listing format} et de l'option \mintinline{text}|--color|:
\begin{minted}[escapeinside=||,linenos]{text}
[robert@kiddo courses]$ ls -l --color
total 56
drwxr-xr-x 3 robert robert  4096 12 sept. 21:52 |\textcolor{blue}{fichiers}|
-rw-r--r-- 1 robert robert    88 12 sept. 20:57 ls-R
-rw-r--r-- 1 robert robert   627 12 sept. 15:11 makefile
-rw-r--r-- 1 robert robert   558 12 sept. 11:20 _preamble.tex
-rw-r--r-- 1 robert robert  1254 12 sept. 20:57 README.md
-rw-r--r-- 1 robert robert 27345 12 sept. 20:58 README.pdf
-rw-r--r-- 1 robert robert  1570 12 sept. 12:13 README.tex
-rw-r--r-- 1 robert robert    49 12 sept. 20:57 texfiles
\end{minted}
\begin{quoting}
  \textbf{Remarque} L'option \mintinline{text}|--color| permet de
  distinguer facilement les fichiers et les répertoires.
\end{quoting}

\paragraph{Commentaire}
\label{ref:file-system-blocks}
L'option \mintinline{text}|-l|, \enquote{long listing format}, affiche
d'abord sur la première ligne la somme des \emph{file system blocks}
occupés par les fichiers qui sont listés\footnote{Le \emph{file system
    block} est la plus petite unité d'écriture possible sur un sytème
  de fichiers donné.}. Les fichiers et les répertoires sont ensuite
donnés dans les lignes suivantes. Prenons comme exemple la ligne~4
ci-dessus:
\begin{minted}{text}
-rw-r--r-- 1 robert robert    88 12 sept. 20:57 ls-R
\end{minted}
Il faut l'analyser en dix parties, de la façon suivante:
\bgroup\ttfamily
\begin{xltabular}{1.0\linewidth}{XXXXXXXXXX}
  \toprule
  1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\ \midrule\endhead
  - & rw- & r-- & r-- & 1 & robert & robert & 88 & 12 sept. 20:57 &
                                                                    ls-R
  \\
  \bottomrule
\end{xltabular}
\egroup

Voici une analyse simplifiée de cette ligne. Retenez que d'autres
valeurs que celles qui sont commentées ci-dessous sont possibles.
\begin{enumerate}
\item Peut avoir les valeurs suivantes:
  \begin{itemize}
  \item \mintinline{text}|-| pour les fichiers;
  \item \mintinline{text}|d| pour les répertoires;
  \item \mintinline{text}|l| pour les liens.
  \end{itemize}
\item Permissions données au propriétaire. Il y a trois types de
  permissions que vous devez connaître ici:
  \begin{itemize}
  \item \mintinline{text}|-|: aucune permission;
  \item \mintinline{text}|r|: permission en lecture;
  \item \mintinline{text}|w|: permission en écriture;
  \item \mintinline{text}|x|: permission en exécution.
  \end{itemize}
  La première position représente les droits en \emph{lecture}
  (valeurs possibles: \mintinline{text}|-| ou \mintinline{text}|r|);
  La deuxième position représente les droits en \emph{écriture}
  (valeurs possibles: \mintinline{text}|-| ou \mintinline{text}|w|);
  La troisième position représente les droits en \emph{exécution}
  (valeurs possibles: \mintinline{text}|-| ou \mintinline{text}|x|).
\item Permission de \emph{groupe}. Les groupes peuvent réunir
  plusieurs utilisateurs. Par exemple, on peut créer un groupe
  \emph{travail} et y mettre plusieurs utilisateurs qui auront ainsi
  des permissions communes sur les fichiers et les répertoires.
\item Permissions données à tout le monde.
\item Le nombre de liens sur le fichier ou le répertoire listé. Un
  fichier a en principe au moins un lien tandis qu'un répertoire en a
  au moins deux car le système considère que le répertoire parent et
  le répertoire courant (\mintinline{text}|..| et
  \mintinline{text}|.|, voir \emph{supra}
  \vref{ref:parent-current}) sont des liens.
\item Le nom du propriétaire du fichier.
\item Le nom du groupe dont les membres peuvent avoir des permissions
  sur le fichier.
\item La taille du fichier mesurée en \emph{bytes}\footnote{Le
    \emph{byte} est une séquence de 8 \emph{bits} traitée comme une
    seule unité d'information. Le \emph{bit} de données peut avoir deux
    valeurs: 0 ou 1, ce nous qui rappelle que les ordinateurs sont des
    machines électriques dans lesquelles le courant peut passer (1) ou
    ne pas passer (0). L'unité conventionnelle du \emph{bit} est
    \unit{b} tandis que l'unité du \emph{byte} est \unit{B}. Il ne
    faut pas les confondre.}.
\item La date à laquelle  le fichier a été créé ou modifié pour la
  dernière fois.
\item Le nom du fichier.
\end{enumerate}
\index[cmds]{ls|)}

\chapter{Bash, le shell}
\label{cha:bash-le-shell}
Ce que vous montre le terminal, à savoir l'invite de commande ou
\emph{prompt} en anglais, s'appelle le \emph{shell}. Il y a plusieurs
types de \emph{shells}, mais le plus connu s'appelle
\emph{bash}\footnote{Pour \emph{bourne again
    shell}.}. La~\vref{sec:prem-comm} vous a appris une première série
de commandes.

Les commandes portent sur les \emph{fichiers}. Avant de continuer, il
faut savoir que sous Linux \emph{tout est fichier}: un fichier texte
est un fichier, mais un répertoire aussi, de même que le clavier,
l'écran et tous les périphériques de l'ordinateur sont des
fichiers. Ainsi, un programme vidéo qui joue un film ne fait pas autre
chose que copier des séquences vidéo vers le fichier qui désigne
l'écran et des séquences son vers le fichier qui désigne la carte
son.

La deuxième chose à savoir est que Linux est un système dit \emph{sans
  extension}. L'\emph{extension} est une séquence de 1 à 4 caractères
placée après un point dans un nom de fichier. Elle permet de connaître
quel est le type de chaque fichier. Par exemple, c'est par l'extension
que l'on saura que \verb+fichier.png+ est un fichier image.

À la différence d'autres systèmes informatiques, Linux ne fait aucun
cas de l'extension mais regarde directement à l'intérieur de chaque
fichier pour en déterminer le type.

\paragraph{file}\index[cmds]{file|textbf}
La commande \mintinline{text}|file| permet de tout savoir sur les
types de fichiers. Nous pouvons la lancer sur la racine de notre dépôt
Git:
\begin{minted}[linenos]{text}
[robert@kiddo courses]$ file *
fichiers:      directory
ls-R:          ASCII text
makefile:      makefile script, ASCII text
_preamble.tex: LaTeX 2e document, ASCII text
README.md:     UTF-8 Unicode text
README.pdf:    PDF document, version 1.5
README.tex:    LaTeX 2e document, UTF-8 Unicode text
texfiles:      ASCII text
\end{minted}
\begin{quoting}
  \textbf{Remarques:}
  \begin{enumerate}
  \item Les éléments des lignes 2, 3, 4 et 9 n'ont pas d'extension
    mais Linux détermine leur type de façon précise.
  \item À la suite de la commande \mintinline{text}|file|, le
    caractère \mintinline{text}|*| a une signification spéciale: il
    désigne toute séquence formée par zéro ou plus de caractères: on
    l'a utilisé ici pour lister tous les fichiers du répertoire
    courant (v. \emph{infra} \vref{sec:wildcards} pour plus de
    détails).
  \end{enumerate}
\end{quoting}

\paragraph{Minuscules et majuscules}
À savoir également: Linux est sensible à la casse dans les noms des
fichiers. Ainsi, \verb+fichier.txt+ et \verb+Fichier.txt+ sont deux
fichiers différents.

\paragraph{Espaces}
Soit la commande suivante:
\begin{minted}{text}
[robert@kiddo courses]$ ls -l README.md README.pdf
-rw-r--r-- 1 robert robert  1254 13 sept. 08:14 README.md
-rw-r--r-- 1 robert robert 27345 13 sept. 08:15 README.pdf
\end{minted}
Comme on l'a vu plus haut (\vref{sec:options}), le \emph{shell} n'a
pas de mal à distinguer l'\emph{option courte} des \emph{arguments}
car à la différence des arguments, l'option est préfixée par le signe
\mintinline{text}|-|. La commande est donc interprétée de la façon
suivante: \enquote{veuillez donner des informations au \emph{format
    long} sur les deux fichiers \texttt{README.md} et
  \texttt{README.pdf}}.

C'est donc l'\emph{espace} qui sert à délimiter les options et les
arguments dans les commandes du \emph{shell}. Techniquement, comme
l'espace est interprété comme un délimiteur, on dit que c'est un
\emph{caractère actif} du \emph{shell}. Ainsi, dans une ligne de
commande, un fichier nommé \verb+photos de vacances.zip+ sera
interprété comme une suite distincte de trois arguments:
\begin{enumerate}
\item \verb+photos+
\item \verb+de+
\item \verb+vacances.zip+
\end{enumerate}
Et le \emph{shell} ne pourra pas le trouver. Il y a deux solutions
possibles:
\begin{enumerate}\label{ref:guillemets-simples-intro}
\item Placer le nom du fichier entre guillemets simples:
\begin{minted}{text}
[robert@kiddo courses]$ ls 'photos de vacances.zip'
'photos de vacances.zip'
\end{minted}
\item Préfixer les espaces par ce qu'on appelle l'\emph{escape
    character} qui est le \emph{backslash} (\verb+\+) 
\begin{minted}{text}
[robert@kiddo courses]$ ls photos\ de\ vacances.zip
'photos de vacances.zip'
\end{minted}
  Le rôle du caractère d'échappement est en effet d'annuler la
  signification particulière du caractère qui le suit. Or dans le
  \emph{shell}, l'espace est un \emph{caractère actif} puisqu'il est
  le délimiteur entre les commandes, les options et les arguments.
\end{enumerate}
\begin{quoting}
  On comprendra qu'il vaut mieux éviter d'utiliser les espaces dans
  les noms des fichiers. À la place des espaces, on utilisera le
  caractère de soulignement ou \emph{underscore}:
  \verb+photos_de_vacances.zip+
\end{quoting}

\paragraph{Fichiers cachés}
Tout fichier dont le nom commence par un point (\mintinline{text}|.|)
est considéré comme un fichier caché. Le plus souvent, les fichiers
cachés contiennent des paramètres de configuration. La commande
\index[cmds]{ls}\mintinline{text}|ls| est capable de les afficher si
on lui passe l'option \mintinline{text}|-a| pour
\emph{all}. Appliquons cette option sur notre dépôt Git:
\begin{minted}[escapeinside=||,linenos]{text}
[robert@kiddo courses]$ ls -la
total 72
drwxr-xr-x 4 robert robert  4096 13 sept. 12:44 .
drwxr-xr-x 6 robert robert  4096 10 sept. 11:04 ..
drwxr-xr-x 3 robert robert  4096 13 sept. 12:44 |\textcolor{blue}{fichiers}|
drwxr-xr-x 8 robert robert  4096 13 sept. 11:29 |\textcolor{blue}{.git}|
-rw-r--r-- 1 robert robert    19  1 août   2017 .gitignore
-rw-r--r-- 1 robert robert    88 13 sept. 08:14 ls-R
-rw-r--r-- 1 robert robert   627 12 sept. 15:11 makefile
-rw-r--r-- 1 robert robert   588 13 sept. 11:29 _preamble.tex
-rw-r--r-- 1 robert robert  1254 13 sept. 08:14 README.md
-rw-r--r-- 1 robert robert 27345 13 sept. 08:15 README.pdf
-rw-r--r-- 1 robert robert  1570 12 sept. 12:13 README.tex
-rw-r--r-- 1 robert robert    49 13 sept. 08:14 texfiles
\end{minted}
Nous voyons ainsi apparaître à la ligne~6 un répertoire caché et à la
ligne~7 un fichier caché.

\section{Commandes courantes}
\label{sec:commandes-courantes}

Ces commandes s'ajoutent à celles qui sont décrites plus haut
(\vref{sec:prem-comm}).

\paragraph{mkdir}\index[cmds]{mkdir|textbf}
Sert à créer un nouveau répertoire. L'option \mintinline{text}|-p|
peut-être utilisée si l'on veut créer d'un coup un répertoire et un ou
plusieurs sous-répertoires. L'option \mintinline{text}|-v|, pour
\emph{verbose}, demande aussi à \verb|mkdir| de retourner un message
de confirmation:
\begin{minted}{text}
[robert@kiddo courses]$ mkdir -pv sandbox/robert
mkdir: création du répertoire 'sandbox'
mkdir: création du répertoire 'sandbox/robert'
\end{minted}

\paragraph{touch}\index[cmds]{touch|textbf}
Sert à créer un fichier vide dont le nom est passé en argument. Cette
commande sert également à modifier les métadonnées de temps associées
aux fichiers (date de création et/ou de modification).

L'exemple suivant montre comment créer un nouveau dossier dans lequel
on crée également un fichier vide \verb|fichier.txt|. Ensuite, on
utilise la commande \index[cmds]{mv}\verb|mv| pour \emph{déplacer} ce
fichier vers un autre fichier \verb|fichier-mk2.txt| au même
endroit. Le résultat de cette action particulière, le
\emph{déplacement au même endroit}, est tout simplement de renommer le
fichier. Enfin, la commande %
\index[cmds]{ls}\verb|ls -l| sert de moyen de contrôle:
\begin{minted}{text}
[robert@kiddo courses]$ mkdir -pv sandbox
mkdir: création du répertoire 'sandbox'
[robert@kiddo courses]$ touch sandbox/fichier.txt
[robert@kiddo courses]$ mv sandbox/fichier.txt sandbox/fichier-mk2.txt 
[robert@kiddo courses]$ ls -l sandbox/
total 0
-rw-r--r-- 1 robert robert 0 13 sept. 15:51 fichier-mk2.txt
\end{minted}

\subsection{Commandes destructives}
\label{sec:comm-destr}

\paragraph{rm}\index[cmds]{rm|textbf}
Pour \emph{remove}. Il suffit de passer en argument à cette commande
ce que l'on souhaite détruire. Par défaut, cette commande ne détruit
pas les répertoires. Elle accepte une série d'options dont voici les
plus importantes:
\begin{description}
\item[-i] demande une confirmation à chaque opération de destruction.
\item[-f] pour \emph{force}; fait le contraire de \verb|-i|.
\item[-r] pour \emph{recursive}; détruit les répertoires et leur
  contenu.
\end{description}

\begin{mdframed}[backgroundcolor=Cyan]
Cette commande doit être exécutée avec précaution car il n'y a aucun
retour en arrière possible.
\end{mdframed}

Par exemple, soit le répertoire \verb|sandbox|. La commande:
\begin{minted}{text}
[robert@kiddo courses]$ rm -rf sandbox
\end{minted}
détruira sans aucune demande de confirmation à la fois le répertoire
\verb|sandbox| et tout ce qu'il contient, fichiers, répertoires et
sous-répertoires.

Pour donner une idée de la puissance de destruction de cette commande,
la ligne suivante:
\begin{minted}{text}
[robert@kiddo courses]$ rm -rf *
\end{minted}
détruira absolument tout sans demande de confirmation pour ne laisser
que les fichiers cachés du répertoire courant dont le nom commence
par un point.

\section{Wildcards}
\label{sec:wildcards}
Les \emph{wildcards}, ou \enquote{métacaractères} sont des caractères
ou des séquences de caractères qui servent à représenter des séries de
caractères. On les utilise pour construire des schémas de
remplacement. Voici quels sont les plus utilisés:
\begin{itemize}
\item \verb|*| représente zéro ou plus de caractères.
\item \verb|?| représente un caractère unique.
\item \verb|[]| représente une série de caractères. Par exemple,
  \verb|[QGH]| représente l'une des trois lettres majuscules Q, G ou
  H. Ainsi, la commande:
\begin{minted}{text}
ls [QGH]*
\end{minted}
  retournera tous les noms de fichiers qui commencent par l'une de ces
  trois lettres. Pour représenter une \emph{série continue de
    caractères}, on peut utiliser le trait d'union. Par exemple,
  \verb|[a-z]| représente toutes les lettres minuscules non accentuées
  de l'alphabet; et \verb|[A-Za-z]| toutes les lettres non accentuées,
  majuscules ou minuscules.
\end{itemize}

\section{Redirection et chaînage}
\label{sec:redir-et-chain}
Nous avons vu jusqu'ici que les commandes renvoient normalement leur
résultat sur le terminal lui-même. On peut cependant rediriger ce que
les commandes renvoient vers un fichier à l'aide des \emph{opérateurs
  de redirection}. Trois d'entre eux sont utiles à connaître:
\begin{enumerate}
\item \verb|>| redirige vers un nouveau fichier. Si le fichier
  n'existe pas, il est créé. S'il existe, il sera écrasé et remplacé
  par un nouveau fichier du même nom.
\item \verb|>>| fait la même chose que \verb|>|, mais \emph{ajoute} le
  résultat au fichier si celui-ci existe.
\item \verb|<| lit le contenu du fichier dont le nom suit et le passe
  en argument à la commande qui précède pour traitement.
\end{enumerate}

Dans l'exemple qui suit, on demande à la commande
\index[cmds]{ls}\verb|ls -l| de rediriger son résultat vers un fichier
\verb|all-files.txt|. On s'assure que ce fichier a bien été créé, puis
on demande à la commande \index[cmds]{cat}\verb|cat| d'en afficher le
contenu au terminal. Les trois commandes sont entrées aux lignes 1, 2
et 4:
\begin{minted}[escapeinside=||,linenos]{text}
[robert@kiddo courses]$ ls -l > |\textcolor{red}{all-files.txt}|
[robert@kiddo courses]$ ls
|\textcolor{red}{all-files.txt}|  fichiers  ls-R  makefile  _preamble.tex  README.md  README.tex
[robert@kiddo courses]$ cat |\textcolor{red}{all-files.txt}| 
total 24
drwxr-xr-x 3 robert robert 4096 13 sept. 17:15 fichiers
-rw-r--r-- 1 robert robert   88 13 sept. 13:34 ls-R
-rw-r--r-- 1 robert robert  627 12 sept. 15:11 makefile
-rw-r--r-- 1 robert robert  668 13 sept. 15:26 _preamble.tex
-rw-r--r-- 1 robert robert 1254 13 sept. 13:34 README.md
-rw-r--r-- 1 robert robert 1570 12 sept. 12:13 README.tex
\end{minted}

\label{ref:wc-intro}
L'exemple suivant est plus subtil. Il fait appel à une commande,
\verb|wc -l| qui compte les lignes des fichiers\footnote{Voir plus
  loin \vpageref{ref:wc}.}:
\begin{minted}[linenos]{text}
[robert@kiddo courses]$ wc -l makefile 
21 makefile
[robert@kiddo courses]$ wc -l < makefile
21
\end{minted}
Comme on le voit, la commande entrée à la ligne~1 renvoie deux
informations: le nombre de lignes du fichier (21) et le nom du fichier
lui-même. Quant à la commande de la ligne~3, elle utilise l'opérateur
de redirection \verb|<| qui a pour effet de passer en argument à la
commande non pas un nom de fichier à traiter, mais son contenu seul,
lu puis redirigé. C'est une variante anonyme de la commande de la
ligne~1.

\paragraph{Chaînage}
En anglais, \emph{piping}. Comme nous l'avons vu, la redirection
permet d'envoyer des résultats vers des fichiers ou bien des contenus
de fichiers vers des commandes. Le \emph{chaînage} consiste à faire
passer un résultat fourni par une commande à une autre commande censée
en fournir un nouveau traitement. L'opérateur de chaînage est le
caractère \emph{pipe} (\verb+|+).

Avant d'aller plus loin, étudions rapidement deux nouvelles commandes
qui servent à filtrer le contenu des fichiers.

\paragraph{head}\label{ref:head-tail}\index[cmds]{head|textbf}
\mintinline{text}|head -<num> fichier| affiche au terminal les
\verb|<num>| premières lignes d'un fichier. Sans l'option
\mintinline{text}|-<num>|, les 10 premières lignes sont
affichées. Exemple:
\begin{minted}{text}
[robert@kiddo courses]$ head -3 ls-R 
./fichiers/01-ligne-de-commande.tex
./makefile
./_preamble.tex
\end{minted}

\paragraph{tail}\index[cmds]{tail|textbf}
\mintinline{text}|tail -<num> fichier| affiche au terminal les
\verb|<num>| dernières lignes d'un fichier. Sans l'option
\mintinline{text}|-<num>|, les 10 dernières lignes sont affichées.
Exemple:
\begin{minted}{text}
[robert@kiddo courses]$ tail -3 ls-R 
./_preamble.tex
./README.md
./README.tex
\end{minted}
En outre, on peut passer à \verb|tail| l'option %
\mintinline{text}|-n +<num>| qui affiche tout un fichier jusqu'à la
dernière ligne, \emph{mais en commençant à partir de la ligne}
\verb|<num>|. L'exemple suivant en montre une application directe.

Cet exemple reprend des commandes connues. Supposons que l'on veuille
connaître simplement le nombre de fichiers du notre dépôt Git. Nous
savons produire une liste à l'aide de la commande
\index[cmds]{ls}\verb|ls -l|. Nous savons également que la commande
\verb|wc -l| compte les lignes. Cependant, la première ligne retournée
par la commande \verb|ls -l|, qui donne la somme des \emph{file system
  blocks} occupés par le contenu du répertoire, doit être exclue du
compte (voir \emph{supra}, \vpageref{ref:file-system-blocks}). C'est
ici qu'intervient la commande, \verb|tail|, qui retourne les dernières
lignes d'un fichier. Avec l'option \verb|-n +2|, la première ligne
sera ignorée:
\begin{minted}{text}
[robert@kiddo courses]$ ls -l | tail -n +2 | wc -l
6
\end{minted}

\section{Filtrage}
\label{sec:filtrage}

Comme leur nom l'indique, les commandes de filtrage servent à mettre
en forme des fichiers texte tout en sélectionnant certaines parties de
leur contenu.

Nous en avons étudié deux plus haut (\vpageref{ref:head-tail}):
\begin{enumerate}
\item \index[cmds]{head}\verb|head| qui sélectionne les premières
  lignes d'un fichier.
\item \index[cmds]{tail}\verb|tail| qui sélectionne les dernières
  lignes d'un fichier.
\end{enumerate}

On ajoutera ici les commandes suivantes:

\paragraph{cat}\index[cmds]{cat|textbf}
Affiche au terminal tout le contenu d'un fichier:
\begin{minted}{text}
[robert@kiddo courses]$ cat ls-R 
./fichiers/01-ligne-de-commande.tex
./makefile
./_preamble.tex
./README.md
./README.tex
\end{minted}

\paragraph{wc}\label{ref:wc}\index[cmds]{wc|textbf}
Pour \emph{word count}.  Cette commande a été utilisée plus haut une
fois avec l'option \verb|-l| pour compter les lignes d'un fichier
(\vpageref{ref:wc-intro}). Utilisée sans option, elle retourne le
nombre de lignes (\verb|-l|), de mots (\verb|-w|) et de caractères
(\verb|-m|) d'un fichier:
\begin{minted}{text}
[robert@kiddo courses]$ wc makefile 
 21 114 627 makefile
\end{minted}

\paragraph{cut}\index[cmds]{cut|textbf}
Permet de mettre en forme des données. Prenons l'exemple du fichier
suivant: \\ \mintinline{text}|etudiants.txt|
\begin{minted}{text}
Fonsec Sophie 123456 sophie.fonsec@quelquepart.net
Pédot Hector 456789 hector.pedot@ailleurs.org
\end{minted}
Il contient sur chaque ligne un nom, un prénom, un matricule et une
adresse email. Nous souhaitons collecter simplement les données
suivantes:
\begin{enumerate}
\item Nom
\item Prénom
\item email
\end{enumerate}
La commande \verb|cut| peut être utilisée à cet effet avec les deux
options suivantes:
\begin{enumerate}
\item \mintinline{text}|-d| indiquer par quel caractère les données
  sont délimitées (ici un espace).
\item \mintinline{text}|-f| (pour \emph{field} en anglais) pour
  indiquer quelles données doivent être sélectionnées (ici, les
  éléments 1, puis 2, puis 4).
\end{enumerate}
\begin{minted}{text}
[robert@kiddo courses]$ cut -d ' ' -f 2,1,4 etudiants.txt 
Fonsec Sophie sophie.fonsec@quelquepart.net
Pédot Hector hector.pedot@ailleurs.org
\end{minted}

Mais comment faire pour modifier l'ordre des données et les mettre en
forme de façon à placer le prénom avant le nom et avoir les adresses
email entre crochets pointus? Comment faire aussi pour récupérer les
données dans un tableur?

\paragraph{awk}\index[cmds]{awk|textbf}
Ce programme accessible à la ligne de commande permet d'effectuer ce
travail facilement. Il sélectionne les données dans l'ordre que l'on
souhaite à l'aide de variables: \verb|$1|, \verb|$2|, \verb|$3|,
\&c. Il effectue ensuite ce qu'on appelle des \emph{actions},
lesquelles sont spécifiées entre accolades \verb|{}|. Nous allons ici
utiliser l'action \verb|print|. Voici la commande:
\begin{minted}{text}
[robert@kiddo courses]$ awk '{print $2 ";" $1 ";<" $4 ">"}' etudiants.txt 
Sophie;Fonsec;<sophie.fonsec@quelquepart.net>
Hector;Pédot;<hector.pedot@ailleurs.org>
\end{minted}
\begin{quoting}
  \textbf{Commentaire}
  \begin{enumerate}
  \item La totalité de l'argument passé à \verb|awk| a été placée
    entre guillemets simples \verb|' '|. On renvoie sur ce point à la
    règle posée \vpageref{ref:guillemets-simples-intro}.
  \item Entre les accolades, l'instruction \verb|print| accomplit
    successivement les tâches suivantes:
    \begin{enumerate}
    \item Impression du champ 2.
    \item Impression de la chaîne littérale \verb|;| placée entre
      guillemets\footnote{On n'aurait pas pu employer ici les
        guillemets simples car le premier guillemet simple aurait
        évidemment été compris comme le guillemet fermant celui qui se
      trouve juste avant l'accolade ouvrante.}.
  \item Impression du champ 1.
  \item Impression de la chaîne littérale \verb|;<| placée entre
    guillemets.
  \item Impression du champ 4.
  \item Impression de la chaîne littérale \verb|>| placée entre
    guillemets.
    \end{enumerate}
  \end{enumerate}
\end{quoting}
Pour terminer, il suffit de renommer le fichier \verb|etudiants.txt|
en \verb|etudiants.csv| par la commande:\index[cmds]{mv}
\begin{minted}{text}
mv etudiants.txt etudiants.csv
\end{minted}
et de l'ouvrir dans LibreOffice Calc.

\printindex[cmds]
\end{document}
