\input{../_preamble} \usepackage{menukeys} \title{La ligne de commande} \usepackage{dingbat} \usepackage{minted} \setminted{ bgcolor=Lavender, breaklines, breaksymbolright=\small\carriagereturn} \setmintedinline{bgcolor=Lavender} \usepackage{soul} \makeindex[name=cmds, intoc, title={Liste des commandes et instructions}, options={-s \jobname.ist}] \NewDocumentCommand{\commande}{s m O{}}{ \IfBooleanTF{#1}{\index[cmds]{#2@\texttt{#2}|#3textbf}} {\index[cmds]{#2@\texttt{#2}#3}} } \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}:\\ \commande{mkdir}\mintinline{text}{mkdir travail} \item déplacement du fichier \emph{exemple.pdf} dans le dossier travail: \\ \commande{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}\commande*{pwd} 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}\commande*{mv} 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 \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}\commande*{cp} Signifie \emph{copy}. Cette commande copie des fichiers depuis un endroit vers un autre. La syntaxe est comparable à celle de la séquence \commande{mv}\mintinline{text}{mv}. \begin{minted}[showspaces]{text} cp \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}\commande*{cd} 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 \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 \commande{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}\commande*{ls}[(] 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 \hypertarget{lnk_permissions}{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} \commande*{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}\commande*{file} 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 \hypertarget{lnk_guillemets}{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]{\hypertarget{lnk_hidden}{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 \commande{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}\commande*{mkdir} 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}\commande*{touch} 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 \commande{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 % \commande{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}\commande*{rm} 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]{\hypertarget{lnk_wildcards}{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]{\hypertarget{lnk_redirection}{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 \commande{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 \commande{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}\commande*{head} \mintinline{text}|head - fichier| affiche au terminal les \verb|| premières lignes d'un fichier. Sans l'option \mintinline{text}|-|, 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}\commande*{tail} \mintinline{text}|tail - fichier| affiche au terminal les \verb|| dernières lignes d'un fichier. Sans l'option \mintinline{text}|-|, 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 +| qui affiche tout un fichier jusqu'à la dernière ligne, \emph{mais en commençant à partir de la ligne} \verb||. 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 \commande{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 \commande{head}\verb|head| qui sélectionne les premières lignes d'un fichier. \item \commande{tail}\verb|tail| qui sélectionne les dernières lignes d'un fichier. \end{enumerate} On ajoutera ici les commandes suivantes: \paragraph{cat}\commande*{cat} 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}\commande*{wc} 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}\commande*{cut} 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}\commande*{awk} 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; Hector;Pédot; \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:\commande{mv} \begin{minted}{text} mv etudiants.txt etudiants.csv \end{minted} et de l'ouvrir dans LibreOffice Calc. \printindex[cmds] \end{document}