From 1adacb29a6f82f571afd38c759e22bcf3e9e8a08 Mon Sep 17 00:00:00 2001 From: Robert Alessi Date: Wed, 3 Oct 2018 10:15:23 +0200 Subject: made some room for a 02-*.tex file to come --- fichiers/02-tableur_bdd.tex | 405 ---------- fichiers/03-grep-bash.tex | 1226 ------------------------------- fichiers/03-tableur_bdd.tex | 405 ++++++++++ fichiers/04-grep-bash.tex | 1226 +++++++++++++++++++++++++++++++ fichiers/images/02-ascii.png | Bin 96404 -> 0 bytes fichiers/images/02-donnees1.png | Bin 33951 -> 0 bytes fichiers/images/02-donnees2.png | Bin 11503 -> 0 bytes fichiers/images/02-exercice_formats.png | Bin 17450 -> 0 bytes fichiers/images/02-unicode.png | Bin 87510 -> 0 bytes fichiers/images/03-ascii.png | Bin 0 -> 96404 bytes fichiers/images/03-donnees1.png | Bin 0 -> 33951 bytes fichiers/images/03-donnees2.png | Bin 0 -> 11503 bytes fichiers/images/03-exercice_formats.png | Bin 0 -> 17450 bytes fichiers/images/03-unicode.png | Bin 0 -> 87510 bytes 14 files changed, 1631 insertions(+), 1631 deletions(-) delete mode 100644 fichiers/02-tableur_bdd.tex delete mode 100644 fichiers/03-grep-bash.tex create mode 100644 fichiers/03-tableur_bdd.tex create mode 100644 fichiers/04-grep-bash.tex delete mode 100644 fichiers/images/02-ascii.png delete mode 100644 fichiers/images/02-donnees1.png delete mode 100644 fichiers/images/02-donnees2.png delete mode 100644 fichiers/images/02-exercice_formats.png delete mode 100644 fichiers/images/02-unicode.png create mode 100644 fichiers/images/03-ascii.png create mode 100644 fichiers/images/03-donnees1.png create mode 100644 fichiers/images/03-donnees2.png create mode 100644 fichiers/images/03-exercice_formats.png create mode 100644 fichiers/images/03-unicode.png diff --git a/fichiers/02-tableur_bdd.tex b/fichiers/02-tableur_bdd.tex deleted file mode 100644 index d6219d5..0000000 --- a/fichiers/02-tableur_bdd.tex +++ /dev/null @@ -1,405 +0,0 @@ -\input{../_preamble-ed.tex} -\usepackage{comment} - -\usepackage[toc]{multitoc} -\usepackage{graphicx} -\graphicspath{{images/}} - -\title{Tableur et base de données} - -\usepackage{hyperref} - -\begin{document} -\maketitle -\renewcommand{\contentsname}{Sommaire} -\tableofcontents - -\chapter{Qu'est-ce qu'une donnée?} - -\section{Définitions} -Une donnée est un élément brut, qui n'a pas encore été interprété, mis -en contexte. La mise en contexte crée de la valeur ajoutée pour -constituer une information (on peut définir l'information comme -l'interprétation d'une source de données). Les données brutes peuvent -être entrées dans un programme informatique ou utilisées dans des -procédures manuelles comme l'analyse statistique d'une enquête par -exemple. - -Qu'entend-on maintenant par \enquote{données publiques}? Ce sont les -données qui figurent dans les documents communiqués ou publiés par les -administrations. À partir de là, quand on parle d'\emph{open data}, il -s'agit de la mise à disposition de tous les citoyens sur internet des -données publiques ayant vocation à être librement accessibles et -gratuitement réutilisables. Ces données sont diffusées de manière -structurée selon une licence ouverte garantissant leur libre accès et -leur réutilisation par tous, sans restriction technique, juridique ou -financière. Cela signifie que n'importe quel utilisateur peut utiliser -ces données, les modifier ou les partager (même à des fins -commerciales). - -Il y a enfin une autre expression que vous avez certainement -entendues: celle de \emph{big data} qui désigne littéralement les -\enquote{grosses données}. Qu'entend-on par là? Les vibrations de tel -tablier de pont, les sentiments exprimés sur tel réseau social, les -achats ou recherches sur tel site… Toutes ces données, utiles pour la -maîtrise de machines ou notre vie sociale, économique, voire -sentimentale, laissent des traces, des scories, qui sont de plus en -plus souvent conservées. C’est de cette profusion de données sur de -nombreux domaines que résultent les Big Data ou mégadonnées. On le -voit, ces Big Data désignent des ensembles de données tellement -volumineux qu'il devient difficile, voire impossible, de les manipuler -avec des outils classiques de gestion de base de données ou de gestion -de l'information. - - -\section{Formats} En fonction de ce que l'on veut faire, les -données informatiques sont rangées dans des fichiers. Le choix de la -méthode de rangement, c'est ce qu'on appelle le format. Pour -l'utilisateur, le format est représenté par une extension. Le format -est déterminé par le logiciel au moment de l'enregistrement d'un -document. Comme vous l'avez certainement constaté, le système associe -par défaut un logiciel à un format, raison pour laquelle, quand vous -double-cliquez sur un document, il s'ouvre automatiquement sans que -vous ayez à préciser quel logiciel doit l'ouvrir. Avant de vous -présenter les différents formats que vous devez connaître, sachez que -chaque format relève d'une logique, d'une structure. On en distingue -trois. - - -\paragraph{les principales structures utilisées}: voici les trois -principales structures utilisées pour présenter les données: -\begin{enumerate} -\item la structure tabulaire: c'est la plus répandue. On organise les -données dans des colonnes et des lignes. Voir par exemple les données -concernant la fréquentation des musées italiens: -\url{http://www.datiopen.it/opendata/Visitatori_musei_pubblici_e_similari_titolo_d_accesso#ui-tabs-3}. Un -des formats qui relève de cette structure est le format csv -(Comma-separated values); il permet d'organiser des données en -cellules afin qu'elles soient traitées par un tableur ou insérées dans -une base de données. Les données dans un document csv sont le plus -souvent encadrées par des guillemets et séparées par des points -virgule. - -\begin{figure}[h] \centering \includegraphics[scale=0.6]{02-donnees2.png} -\end{figure} - -\item la structure hiérarchique: les données présentées ainsi montrent -les rapports entre les points de données comme pour un arbre -généalogique. - -\item la structure en réseau: les données structurées ainsi permettent -des rapports entre n'importe quelle combinaison d'éléments dans -n'importe quelle direction. Le web en est un bon exemple puisque les -pages web comportent des liens vers un nombre incalculable d'autres -pages. Cf. le format xml (Extensible Markup Language) qui a pour -objectif de faciliter l'échange automatisé de contenus complexes. Un -document xml est constitué d'un prologue qui indique les informations -de traitement (comme le jeu de caractères utilisé), et du corps du -document, constitué d'un ensemble de balises qui décrivent les données -(se présentant sous la forme d'une arborescence). Où trouve-t-on du -xml? Dans les pages web, les documents OpenOffice sont également des -fichiers xml, les logiciels de dessin comme InkScape utilisent aussi -ce format, etc. - -\begin{figure}[h] \centering \includegraphics[scale=0.6]{02-donnees1.png} -\end{figure} - -NB: vous remarquerez que les mêmes données peuvent être présentées -sous des formats différents. -\end{enumerate} - -\paragraph{les formats que vous devez savoir utiliser}: on distingue -les formats ouverts dont les spécifications sont publiquement -accessibles des formats fermés qui sont souvent propriétaires (même -quand un format propriétaire est ouvert, les entreprises qui le -commercialisent tentent d'en conserver le contrôle en proposant de -nouvelles versions plus élaborées ou en ayant recours aux -brevets). Voici la liste des principaux formats que vous -rencontrerez. Vous penserez à préciser quels sont ceux qui sont -ouverts. - -\begin{figure}[h] \centering -\includegraphics[scale=0.6]{02-exercice_formats.png} -\end{figure} - -Sur le format txt: éditeur de textes et traitement de -textes. Qu’est-ce qu’un éditeur de textes ? À quoi cela sert-il ? -Est-ce la même chose qu’un traitement de texte ? Un éditeur de texte -est un programme qui permet de modifier des fichiers de texte brut, -sans mise en forme (gras, italique, souligné…). Sous Windows, on -dispose d’un éditeur de texte très basique, le Bloc-Notes, mais il -existe aussi NotePad++ (plus évolué). Sous Linux, on a le choix entre -Nano, Vim, Emacs, et bien d’autres. Un traitement de texte, en -revanche, est fait pour rédiger des documents mis en forme. Word et -LibreOffice Writer sont certainement les plus célèbres. - - -\paragraph{Exercice 1} - -Quand a-t-on besoin d’un éditeur de texte ? Chaque fois qu’on veut -éditer un fichier de texte brut (au format .txt). Si les éditeurs de -texte sont parfaits pour les programmeurs, ils sont aussi utiles pour -retravailler du texte à l’aide de commandes puissantes, avant de le -structurer dans un traitement de textes. Exemple : quand on récupère -une œuvre ou un extrait d’œuvre depuis une bibliothèque numérique, il -faut très souvent supprimer les retours à la ligne intempestifs qu’on -appelle hard wrap. Il est très facile de le faire grâce à un éditeur -comme Notepad++ : allez dans le menu TextFX, commande TextFXEdit, -sous-commande Unwrap Text. Les retours à la ligne simples sont -convertis en fin de ligne (mode soft wrap) tandis que les doubles -retours subsistent. À ce problème, s’ajoute parfois aussi celui de -caractères cabalistiques qui apparaissent à la place des caractères -accentués. - -\paragraph{Exercice 2} -\begin{enumerate} -\item Récupérez au format txt sur Gutenberg \emph{Le corbeau} de Poe -et ouvrez-le dans LibreOffice ; -\item Faites apparaître au début du document le titre de l’œuvre en -italique (comme il se doit), puis enregistrez ce fichier au format -natif d’OO (.odt). Enregistrez maintenant ce fichier au format txt et -ouvrez-le avec un éditeur de textes par exemple : commentez la -différence ; -\item Exportez-le enfin au format pdf et veillez à ce que l’ouverture -de ce fichier soit protégé par un mot de passe que vous définirez. -\end{enumerate} - - -\section{Le problème des données textuelles: coder du texte} -\paragraph{Encodage binaire} -C'est dans les années 60 qu'apparaît la -nécessité de représenter chaque caractère en code traitable par -l'ordinateur. Or la mémoire d'un ordinateur n'est capable -d'enregistrer qu'une suite de 0 et 1 (encodage binaire): à l'origine, -les lettres de l'alphabet ont donc été encodées sous la forme d'une -suite de 0 et de 1. - - -\paragraph{La table ASCII} Mais de quel alphabet parle-t-on? Tout -commence par une constatation très simple : les premiers -informaticiens parlaient anglais. Et l’anglais s’écrit avec peu de -choses : deux fois 26 lettres, 10 chiffres, une trentaine de signes de -ponctuation, de signes mathématiques, sans oublier le symbole -dollar. : avec 95 caractères au total on peut se débrouiller. À -l’époque dont je parle, on ne pouvait utiliser que la moitié des -octets, soit 128 valeurs. On en a pris 33 comme caractères de « -contrôle » (comme le retour à la ligne par exemple), plus les 95 dont -on avait besoin pour écrire l’anglais. On a donc attribué des numéros -à toutes ces valeurs : le code ASCII (American Standard Code for -Information Interchange) était né. Voir la figure \ref{ascii}. - -\begin{figure}[h] \centering \includegraphics[scale=0.5]{02-ascii.png} -\caption{La table ASCII} -\label{ascii} -\end{figure} - - -\paragraph{L'unicode} Mais au bout d’un certain temps est apparue la -nécessité de taper du français ou de l’allemand: on a donc utilisé les -valeurs laissées de côté par l’ASCII et il a été possible de caser les -caractères accentués et divers autres symboles utilisés par les -langues d’Europe de l’ouest. Dans ces 128 valeurs, il n’y a hélas pas -eu de place pour les caractères des langues occidentales et l’alphabet -cyrillique et l’alphabet grec et l’alphabet hébreu. Pour pouvoir -taper plusieurs langues sur un même ordinateur et pour que les -ordinateurs puissent communiquer entre eux, des organismes de -standardisation ont créé des tables de correspondance, comme -l’ISO-8859-1, qui propose un jeu de caractères pour les langues -occidentales, l’ISO-8859-5 qui offre du cyrillique, l’ISO-8859-7, qui -propose du grec, etc. Mais, malgré tout, il n’a pas été possible de -faire rentrer les 1945 idéogrammes du japonais officiel dans un octet, -ni les 11 172 syllabes coréennes, ni les dizaines de milliers -d’idéogrammes chinois qu’on arrive à recenser... Pour résoudre -durablement tous ces problèmes de langues, au début des années 2000, -s’est formé un consortium regroupant des grands noms de l’informatique -et de la linguistique : le consortium Unicode. Sa tâche : recenser et -numéroter tous les caractères existant dans toutes les langues du -monde. Est donc né un jeu universel de caractères, acceptant plusieurs -encodages, l’unicode. En 2007, le standard publié comportait environ -60 000 caractères. Prenons, par exemple, le sigma majuscule: il a été -encodé avec le point de code \texttt{U+03A3} (voir la figure -\ref{unicode}). - -Mais l'unicode prend beaucoup plus de place que l'ASCII. Or, pour -prendre l'exemple du français, la grand majorité des caractères -utilisent seulement le code ASCII. On a donc imaginé l'UTF-8 (Unicode -Transformation Format): un texte en UTF-8 est partout en ASCII et dès -qu'on a besoin d'un caractère appartenant à l'unicode on utilise un -caractère spécial pour l'indiquer. - - -\begin{figure}[h] \centering \includegraphics[scale=0.7]{02-unicode.png} -\caption{Aperçu de la table de codage unicode pour l'alphabet grec} -\label{unicode} -\end{figure} - -Cela dit, comment faire pour saisir une citation en espagnol, chinois, -arabe ou grec ancien au milieu d’un texte en français ? Il faut non -seulement disposer d’une police unicode (comme Gentium), mais encore -d’un clavier virtuel qui vous permet de savoir où se trouvent les -caractères. Ainsi, pour être en mesure de saisir du texte dans une -langue autre que le français, vous devez attribuer à votre clavier la -langue de saisie souhaitée. Par exemple, pour taper οὐκ ἔλαβον πόλιν, -vous devez configurer votre clavier de façon à saisir π quand vous -tapez sur la touche P. Pour ce faire, il suffit de cliquer du droit -sur l’icône FR, puis de choisir «~Paramètres~» et «~Ajouter~». Il -vous est aussi possible d’utiliser des claviers virtuels en ligne, -comme celui disponible à l’adresse suivante : -http://www.lexilogos.com/clavier/multilingue.htm - -\section{Coder des images} Une image se décompose en points appelés -pixels (premier critère de qualité d'une image). À chaque pixel est -associée une couleur décomposée en trois composantes, rouge, vert et -bleu, chacune étant notée par un nombre entre 0 et 255. Exemple: le -code pour le bleu ciel est (119, 181, 254), chaque nombre représentant -le dosage nécessaire de chacune des couleurs primaires pour obtenir la -couleur désirée. C'est ce qu'on appelle le code RVB (Red Green -Blue). Notez que le poids d'une image correspond à 3*nombre de pixels. - - -\chapter{Le tableur: fonctionnalités simples} -Un classeur permet de stocker des données numériques en vue de calculs -ou d'affichages graphiques (par opposition à l'affichage texte qu'on -vient de voir avec le format csv). Chaque classeur peut contenir de -nombreuses feuilles qu'on sélectionne avec des onglets. Chaque feuille -de calcul permet de saisir, contrôler, répertorier et analyser des -données (textuelles, numériques, fonctionnelles, etc.). Elle contient -des cellules éventuellement regroupées en plages. - -\section{Mise en forme} Chaque cellule peut être mise en forme avec -une palette complète d'outils. Il est possible de reproduire la mise -en forme à une autre cellule ou plage (voir le pinceau brosse). - -Dans un tableur, on peut insérer des graphiques dont on règle les -dimensions, les axes, les légendes et titres. En fonction du type de -données, on pourra privilégier le graphique en histogramme, en lignes -et courbes (pour représenter des tendances ou une évolution dans le -temps de valeurs numériques), à nuage, en secteurs (ou camemberts). - -\section{Fonctions de calcul} Voir la moyenne. - -\section{Tri, filtre et conversion de données} -\paragraph{Tri} Il est possible de trier des données en fonction de -textes (tri croissant ou décroissant), de nombres, de dates. Plusieurs -critères peuvent être définis (ex.: classement d'une classe par ordre -alphabétique des noms puis des notes obtenues). Pensez à cliquer sur -l'onglet Options pour déterminer les options de tri: vous pourrez -ainsi indiquer que la plage contient des étiquettes de colonne afin -d'éviter que les en-têtes de colonne soient triés avec les autres -données. - -\paragraph{Filtre} Le filtre automatique (Données>AutoFiltre) permet -de faciliter la recherche d'informations au sein d'une plage de -données. L'utilisateur peut ainsi choisir des informations qu'il -souhaite afficher ou masquer. - -\paragraph{Conversion} Une fonction permet de diviser une colonne de -données texte en plusieurs colonnes (Données>Texte en colonnes). Ex.: -à partir d'un nom complet, vous voulez une colonne nom et une colonne -prénom. - - -\section{Importation d'une source de données} -On peut vouloir importer une source de données dans un tableur, par -exemple une liste au format texte (qu'on peut visualiser dans un -traitement de textes en affichant les caractères non imprimables): -chaque caractère tabulation délimite le champ d'une cellule et chaque -pied de mouche indique qu'il faut passer à la ligne. Commençons par -ouvrir cette source de données (Fichier>Ouvrir): il faut alors -indiquer que le séparateur est la tabulation. - - -\chapter{Le tableur comme base de données} Un document Calc peut -constituer une base de données simplifiée. Dans une base de données, -un enregistrement est un groupe d'éléments de données liés entre eux -et traités comme une seule unité d'information. Chaque élément dans -l'enregistrement est appelé un champ. Une table est un ensemble -d'enregistrements. Chaque enregistrement, à l'intérieur d'une table, a -la même structure. Une table peut être vue comme une série de lignes -et de colonnes. On le voit, une feuille d'un document Calc a une -structure similaire à une table de base de données. - -Nous allons définir une plage de base de données de façon à trier, -grouper, rechercher et effectuer des calculs avec la plage comme si -c'était une base de données (Données>Définir la plage). - -\section{Utiliser des critères de recherche pour trouver des -données} -\paragraph{Exemple n°1} Comment compter toutes les cellules d'une -plage de données dont le contenu correspond à des critères de -recherche que nous aurons définis. Hypothèse de travail: nous -recherchons le nombre d'étudiants de la base dont la moyenne est égale -ou supérieure à 10 OU dont l'âge est inférieur ou égal à 17. Voici ce -qu'on doit saisir dans la cellule H5: -\begin{verbatim} =BDNB(A9:G51;0;A1:G3) -\end{verbatim} - -\paragraph{Commentaire} Le nom de la fonction est suivi d'une -parenthèse dans laquelle figurent: -\begin{itemize} -\item la plage de cellules contenant les données: A9:G51 -\item le champ de la base (colonne) utilisé pour les critères de -recherche: 0 -\item la plage de cellules contenant les critères de recherche: A1:G3 -\end{itemize} - -\paragraph{Exemple n°2} Comment déterminer le contenu de la cellule -d'une plage de données correspondant aux critères de -recherche. Hypothèse de travail: nous recherchons le nom de l'étudiant -qui a obtenu 5/20 au devoir n°1: -\begin{verbatim} =BDLIRE(A9:G51;"PRÉNOM";A1:C2) -\end{verbatim} - - -\section{Utiliser des formules pour trouver des données} Ne prenons -qu'un exemple: la fonction RECHERCHEV (pour recherche verticale): il -s'agit de récupérer des données issues d'une feuille différente de la -feuille de travail grâce à une "clé" commune aux deux feuilles. -\begin{enumerate} -\item dans la feuille n°1, j'ai les noms de tous mes étudiants et leur -n° d'étudiant; -\item dans la feuille n°2, j'ai les noms d'un seul groupe d'étudiants -et leur note. -\end{enumerate} --> Comment faire pour récupérer dans ma deuxième -feuille les n° d'étudiant du seul groupe concerné? -\begin{verbatim} =RECHERCHEV(A2;$Feuille1.$A$1:$B$120;2;0) -\end{verbatim} - -\paragraph{Commentaire} Notez que le premier argument est la valeur -cherchée dans la feuille 1: il s'agit, dans notre exemple, de chercher -l'étudiant Charles-Daniel (cellule A2). - -Le deuxième argument identifie les cellules où effectuer la recherche. - -Le troisième argument identifie la colonne à renvoyer: dans notre -exemple, celle des n° d'étudiants est la deuxième colonne de notre -feuille 1. - -Le dernier argument est facultatif. La valeur par défaut est 1 ou -VRAI, ce qui indique que la première colonne est triée dans l'ordre -croissant. Une valeur de 0 ou FAUX indique que les données ne sont pas -triées. - -Une fois que la recherche a abouti pour le premier étudiant, il faut -étendre la recherche à toutes les données de notre feuille 2: pour -cela, il suffit de faire un copier/coller en ayant pris la précaution -de protéger la formule en encadrant les numéros des colonnes du -chiffre \$. - - -\section{Utiliser des formules pour traiter des - données textuelles} -Plusieurs fonctions permettent de travailler sur du texte. En voici -quelques exemples: -\begin{itemize} -\item Mettre en majuscule la première lettre de chaque mot: -=NOMPROPRE(A1) -\item Supprimer les espaces en trop dans le texte de la cellule A1: -=SUPPRESPACE(A1) -\item Extraire le premier mot d'un texte saisi dans la cellule A1: -=GAUCHE(A1;CHERCHE(" ";A1;1)-1) -\end{itemize} - - - -\end{document} \ No newline at end of file diff --git a/fichiers/03-grep-bash.tex b/fichiers/03-grep-bash.tex deleted file mode 100644 index 48ea55f..0000000 --- a/fichiers/03-grep-bash.tex +++ /dev/null @@ -1,1226 +0,0 @@ -\input{../_preamble} -\input{../_preamble_bbl} -\usepackage{menukeys} -\title{grep et bash} -\usepackage{float} -\usepackage{dingbat} -\usepackage[newfloat]{minted} -\SetupFloatingEnvironment{listing}{listname=Listings} -\setminted{ - bgcolor=Lavender, - breaklines, - breaksymbolright=\small\carriagereturn} -\setmintedinline{bgcolor=Lavender} -\usepackage{capt-of} -\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}} -} - -\NewDocumentCommand{\inputfile}{O{} m m O{application/x-sh}}{ - \marginpar{\attachandlink{scripts/#3}[#4]{Fichier - attaché}{\textcolor{blue}{Ouvrir le fichier}}} - \inputminted[#1]{#2}{scripts/#3} -} - -\begin{document} -\maketitle -\renewcommand{\contentsname}{Sommaire} -\tableofcontents - -\listoflistings - -\needspace{3\baselineskip} -\listoftables - -\chapter{grep, les expressions régulières} -\label{cha:grep-les-expressions}\commande{grep} -Les expressions régulières se rapprochent des \emph{wildcards} ou -\enquote{métacaractères} qui ont été présentés dans -\href{./01-ligne-de-commande.pdf#lnk_wildcards}{le cours sur la ligne - de commande}. C'est une technique commune à pour ainsi dire tous les -langages de programmation qui permet de construire des -\enquote{modèles}, en anglais \emph{patterns}, susceptibles de -capturer des chaînes de caractères. - -Par exemple, soit le fichier suivant: -\begin{minted}{text} -/usr/share/dict/cracklib-small -\end{minted} -Ce fichier fait partie d'un programme dont le rôle est de vérifier la -robustesse des mots de passe. Il contient un grand nombre d'entrées, à -raison d'un mot par ligne. Vérifions cela: -\begin{minted}{text} -[robert@kiddo courses]$ wc -l /usr/share/dict/cracklib-small -54763 /usr/share/dict/cracklib-small -\end{minted} -L'expression régulière suivante retourne tous les mots de cinq lettres -de ce fichier qui commencent par la lettre \verb|c| et se terminent -par la lettre \verb|h|: -\begin{minted}{text} -[robert@kiddo courses]$ grep '\' /usr/share/dict/cracklib-small -catch -cinch -clash -cloth -coach -conch -couch -cough -crash -crush -czech -\end{minted} - -\begin{quoting} - \textsc{Rem.} \verb|grep| recherche les modèles ligne par - ligne et retourne donc un résultat positif dès lors qu'un modèle - donné a été trouvé au moins une fois dans une ligne. -\end{quoting} - -\paragraph{Modèles} -Pour construire les modèles (\emph{patterns}), on peut utiliser les -symboles suivants\footnote{Cette liste n'est pas exhaustive.}: -\begin{xltabular}{\linewidth}{lX} - \toprule - Symbole & Signification \\ \midrule\endhead - \verb|.| & tout caractère unique\\ - \verb|?| & le caractère précédent est répété 0 ou une fois\\ - \verb|*| & le caractère précédent est répété 0 fois ou autant - de fois que possible\\ - \verb|+| & le caractère précédent est répété une fois \emph{au - moins}\\ - \verb|{n}| & le caractère précédent est répété exactement \emph{n} - fois\\ - \verb|{n,m}| & le caractère précédent est répété au moins \emph{n} - fois et au plus \emph{m} fois\\ - \verb|[abc]| & le caractère précédent est l'un de ceux qui se - trouvent entre les crochets droits\\ - \verb|[^abc]| & le caractère précédent n'est pas l'un de ceux qui se - trouvent entre les crochets droits\\ - \verb|[a-z]| & le caractère précédent est compris entre \emph{a} et - \emph{z}, dans l'ordre de la table des - caractères. C'est le sens du trait d'union entre les - lettres \verb|a| et \verb|z|. On peut bien sûr - combiner des chaînes avec et sans trait d'union. Par - exemple, \verb|[A-Ea-e]| correspond aux cinq - premières lettres de l'alphabet, en majuscule et en - minuscule. \\ - \verb|()| & ce qui est inclus entre les parenthèses est traité comme - un groupe \\ - - \verb+|+ & opérateur logique signifiant \emph{ou} \\ - \verb|^| & représente le début de la ligne\\ - \verb|$| & représente la fin de la ligne\\ \\ - \verb|\<| et \verb|\>| & représentent respectivement un début et une - fin de mot\\ - \bottomrule - \caption{grep \emph{patterns}} -\end{xltabular} - -\paragraph{grep, egrep} -\commande*{grep} -\commande{egrep}[|see{\texttt{grep}}] -À la place de \verb|grep|, on peut saisir à la ligne de commande -\verb|egrep| ou \verb|grep -E| pour \emph{extended regular - expressions}. Quelle est la différence? Retenez ici simplement que -sous \verb|grep| les metacaractères -\begin{minted}{text} -? + { } | ( ) -\end{minted} -doivent être précédés de la \emph{séquence d'échappement} \verb|\| -comme ceci: -\begin{minted}{text} -\? \+ \{ \} \| \( \) -\end{minted} -tandis que cela ne se fait pas avec \verb|egrep|. - -\paragraph{options} -La commande \verb|(e)grep| peut recevoir un grand nombre -d'options. Parmi ces options, retenons celles-ci: -\begin{description} -\item[-n] retourne les numéros des lignes dans lesquelles le modèle de - recherche a été trouvé. -\item[-c] retourne le nombre d'occurrences trouvées. -\item[-i] demande à \verb|grep| de ne pas faire de différence entre - les minuscules et les majuscules. -\item[-H] retourne le nom du fichier dans lequel le modèle recherché - est trouvé. -\item[-v] \emph{nie} le modèle recherché: \verb|grep| retournera donc - les lignes dans lesquelles le modèle \emph{n'a pas été trouvé}. -\end{description} - -\paragraph{Exemples} -Les exemples ci-dessous utilisent -\href{./01-ligne-de-commande.pdf#lnk_redirection}{la technique de la - redirection}. -\begin{minted}{text} -[robert@kiddo courses]$ cat /usr/share/dict/cracklib-small | grep '\' | grep 'ea' -scream -seagram -sealteam -seam -sidearm -steam -stream -sunbeam -sunbeam's -\end{minted} - \begin{quoting} - \textbf{Commentaire:} La ligne de commande fait ici successivement - les opérations suivantes: - \begin{enumerate} - \item Concaténation de toutes les lignes du fichier - \verb|cracklib-small| - \item Sélection de tous les mots qui commencent par la lettre - \verb|s| et se terminent par la lettre \verb|m|. - \item Parmi ces mots, sélection de ceux qui contiennent la chaîne - \verb|ea|. - \end{enumerate} - \end{quoting} -\begin{minted}{text} -[robert@kiddo courses]$ cat /usr/share/dict/cracklib-small | grep '\<.....\>' | grep -E 'o{2}|e{2}' | grep 't' | column -c 70 -afoot fleet needn't skeet steep taboo three tweed -beets foote roost sleet steer taboo's three's -boost greet roots sooth stood teems tools -booth hoots scoot steed stool teens tooth -boots loots sheet steel stoop teeth trees -booty meets shoot steen sweet tepee troop -\end{minted} -\begin{quoting} - \textbf{Commentaire:} La ligne de commande fait ici successivement - les opérations suivantes: - \begin{enumerate} - \item Concaténation de toutes les lignes du fichier - \verb|cracklib-small| - \item Sélection des mots de cinq caractères. - \item Parmi ces mots, sélection de ceux qui contiennent \emph{soit} - la chaîne \verb|oo| \emph{soit} la chaîne \verb|ee|. - \item Enfin, sélection, parmi ces derniers mots, de ceux qui - contiennent la lettre \verb|t| - \item La dernière ligne, dont on n'a pas étudié la syntaxe, demande - l'affichage du résultat sous la forme de colonnes tabulées. - \end{enumerate} -\end{quoting} - -\chapter{bash} -\label{cha:bash} -Comme on l'a vu, \verb|bash| est le \emph{shell} le plus répandu sur -les systèmes Linux aujourd'hui. On peut écrire en \verb|bash| des -\emph{scripts}, autrement dit de petits programmes informatiques, pour -réaliser des suites d'opérations plus ou moins complexes. - -Voici un exemple très simple. Prenons les lignes suivantes: -\begin{minted}[linenos]{text} -mkdir sauvegarde -cp *.tex sauvegarde -zip -r sauvegarde.zip sauvegarde -\end{minted} -Ces trois lignes exécutent successivement les opérations suivantes: -\begin{enumerate} -\item Création d'un répertoire intitulé \verb|sauvegarde| -\item Copie de tous les fichiers \TeX{} dans le répertoire - \verb|sauvegarde| -\item Création d'une archive \verb|.zip| de tout le répertoire. -\end{enumerate} - -Pour éviter de répéter ces trois lignes de commande et d'encourir le -risque de se tromper dans la saisie, on peut décider de les écrire -dans un fichier texte que l'on appellera par exemple \verb|backup.sh| -de la façon suivante: -\begin{minted}[linenos]{bash} -#!/bin/bash -mkdir sauvegarde -cp *.tex sauvegarde -zip -r sauvegarde.zip sauvegarde -\end{minted} - -Il suffit alors de demander à \verb|bash| d'exécuter ce fichier pour -que les trois opérations soient réalisées d'un coup. Comme les scripts -écrits en \verb|bash| sont interprétés par le \textsl{shell} -\verb|bash|, \emph{toute ligne de commande peut être exécutée dans un - script}. Réciproquement, \emph{tout ce qui peut entrer dans un - script peut aussi être exécuté à la ligne de commande}. - -\section{L'éditeur de texte} -\label{sec:lediteur-de-texte} -C'est dans un \emph{éditeur de texte} que l'on saisit tout code -informatique. Certains éditeurs de texte sont très simples à -utiliser. Nous allons prendre ici l'exemple de l'un des plus simples, -\verb|nano|. Pour le lancer, il suffit de saisir à la ligne de -commande: \mintinline{text}|nano|. Après avoir lancé \verb|nano| et -saisi le script donné ci-dessus, voici ce que l'on obtient: -\begin{minted}[linenos,fontsize=\footnotesize]{text} - GNU nano 2.8.2 Nouvel espace - -#!/bin/bash -mkdir sauvegarde -cp *.tex sauvegarde -zip -r sauvegarde.zip sauvegarde - - - - - - - - - - - - - - - - - -^G Aide ^O Écrire ^W Chercher ^K Couper ^J Justifier ^C Pos. cur. -^X Quitter ^R Lire fich.^\ Remplacer ^U Coller ^T Orthograp.^_ Aller lig. -\end{minted} - -Les lignes 24 et 25 correspondent au menu de \verb|nano|. On n'y -accède pas par la souris, mais à l'aide des \emph{raccourcis clavier} -qui sont tous préfixés par le \emph{caret} (\verb|^|) qui représente -la touche \keys{Ctrl} du clavier. Donc pour quitter le programme, on -appuiera sur \keys{Ctrl-X}: voici ce que montre \verb|nano| au bas du -terminal après avoir saisi \keys{Ctrl-X}: -\begin{minted}[linenos,fontsize=\footnotesize]{text} -Écrire l'espace modifié ? (Répondre « Non » ABANDONNE les modifications.) - O Oui - N Non ^C Annuler -\end{minted} -Les opérations suivantes sont donc possibles: -\begin{enumerate} -\item \keys{O}: sauvegarde le fichier. -\item \keys{N}: quitte \verb|nano| sans sauvegarder. -\item \keys{Ctrl-C}: annule l'opération et retourne à l'éditeur de texte. -\end{enumerate} -Appuyons sur la touche \keys{O}. \verb|nano| nous invite alors à -entrer le nom du script: -\begin{minted}[linenos,fontsize=\footnotesize]{text} -Nom du fichier à écrire: backup.sh -^G Aide M-D Format DOS M-A Ajout (à la fin)M-B Copie de sécu. -^C Annuler M-M Format Mac M-P Ajout (au début)^T Parcourir -\end{minted} -Après avoir entré le nom du fichier et appuyé sur la touche -\keys{Enter} pour confirmer le choix, on retourne au terminal et à la -ligne de commande. - -\section{Le \emph{shebang}} -\label{sec:le-shebang} -La première ligne du script \verb|backup.sh| donné en exemple -ci-dessus appelle un commentaire particulier: -\begin{minted}[linenos]{bash} -#!/bin/bash -\end{minted} - -Dans cette ligne, la séquence \mintinline{bash}|#!| s'appelle le -\emph{shebang}. Par convention, le \emph{shebang} est un préfixe que -l'on fait suivre du nom du programme qui doit interpréter le script, -précédé de son chemin d'accès absolu. - -Le \emph{shebang} est important car il permet d'accéder aux -interpréteurs auxquels on souhaite accéder depuis la ligne de -commande. Par exemple, pour un script écrit en Python2, la première -ligne sera: -\begin{minted}[linenos]{python} -#!/usr/bin/env python2 -""" - Mon premier script en Python -""" -print("bonjour le monde!") -\end{minted} - -\section{Les commentaires} -\label{sec:les-commentaires} -En \verb|bash|, tout ce qui, sur une même ligne, suit le signe -\mintinline{bash}|#| \emph{n'est ni interprété, ni exécuté}. On -utilise donc ce signe pour introduire des \emph{commentaires} dans le -code informatique. - -Les commentaires ne servent pas uniquement à introduire des remarques -pour son usage personnel. Ils servent aussi, et surtout, à donner des -indications sur le code lui-même pour permettre aux autres de mieux -comprendre la programmation. Si le code est bien commenté, alors on -doit pouvoir le lire comme on lit un livre. Cela est très important -car les programmes longs et complexes dépassent souvent et parfois -même survivent à leur auteur. - -Si le code est bien compris, il sera facilement mis à jour, corrigé et -augmenté par d'autres programmeurs. - -L'art de commenter le code informatique tout en l'écrivant porte le -nom de \emph{literate programming}. Il a été inventé par Donald -E.~Knuth, le créateur de \TeX, qui a posé tous les principes de cet -art dans le cadre de la programmation en -\textsf{WEB}\footnote{\cite{Knuth1983}. Voir également en ligne - \url{http://www.literateprogramming.com/}}. - -Pour un exemple de code commenté, voir le \vref{lst:copyten}. - -\section{Exécution} -\label{sec:execution} -Il faut ici approfondir la notion de \emph{permissions} sur les -fichiers qui a été présentée dans le cours sur la -\href{./01-ligne-de-commande.pdf#lnk_permissions}{ligne - de commande}. Nous avons en effet étudié trois types de permissions -sur les fichiers: en lecture, en écriture et en exécution. Revenons -sur les permissions données par défaut au script \verb|backup.sh|: -\begin{minted}{text} -[robert@kiddo courses]$ ls -l backup.sh --rw-r--r-- 1 robert robert 82 17 sept. 22:06 backup.sh -\end{minted} -Soit: -\begin{itemize} -\item lecture et écriture pour l'utilisateur \verb|robert| (\verb|rw|); -\item lecture seule pour le groupe \verb|robert| (\verb|r|); -\item lecture seule pour le reste du monde (\verb|r|) -\end{itemize} - -\paragraph{chmod} -\commande*{chmod} -La commande qui permet de changer les droits s'appelle -\verb|chmod|. Pour comprendre comment l'utiliser, il faut savoir que -les permissions sont traduites par des valeurs numériques, à savoir: -\begin{itemize} -\item 4 pour le droit \emph{lecture}; -\item 2 pour le droit \emph{écriture}; -\item 1 pour le droit \emph{exécution}. -\end{itemize} -Ces valeurs peuvent être additionnées. On analyse donc ainsi les -permissions sur le fichier \verb|backup.sh|: -\begin{itemize} -\item utilisateur \verb|robert|, lecture + écriture: $4+2=6$; -\item groupe \verb|robert|, lecture: $4$; -\item reste du monde, lecture: $4$. -\end{itemize} -Soit $644$. Pour ajouter à l'utilisateur \verb|robert| seulement la -permission en exécution, il faudrait donc porter cette valeur à -$744$. Nous allons ici donner ce droit à la fois à \verb|robert|, au -groupe \verb|robert| et au reste du monde, soit une valeur de -$755$. La syntaxe est la suivante: -\begin{minted}{text} -chmod xyz -\end{minted} -où \verb|xyz| sont les trois chiffres qui représentent les permissions. -\begin{minted}[escapeinside=||, linenos]{text} -[robert@kiddo courses]$ chmod 755 backup.sh -[robert@kiddo courses]$ ls -l --color backup.sh --rwxr-xr-x 1 robert robert 82 17 sept. 22:06 |\textcolor{green}{backup.sh}| -\end{minted} -\begin{quoting} - \textbf{Commentaire}: - \begin{enumerate} - \item La commande \verb|chmod| a été entrée à la ligne 1. - \item À la ligne 2, nous avons lancé la commande - \commande{ls}\mintinline{text}|ls -l --color| sur le fichier - \verb|backup.sh|: les droits listés à la ligne 3 montrent bien que - la valeur \verb|x| a été ajoutée aux trois endroits possibles. On - voit enfin que l'option \verb|--color| affiche en vert les - fichiers qui sont exécutables. - \end{enumerate} -\end{quoting} - -Nous pouvons désormais exécuter notre script: -\begin{minted}[linenos,escapeinside=||]{text} -[robert@kiddo courses]$ ls -l --color -total 36 --rwxr-xr-x 1 robert robert 82 17 sept. 22:06 |\textcolor{green}{backup.sh}| --rw-r--r-- 1 robert robert 165 16 sept. 19:40 bibliography.bib -drwxr-xr-x 5 robert robert 4096 17 sept. 22:30 |\textcolor{blue}{fichiers}| --rw-r--r-- 1 robert robert 680 16 sept. 18:34 makefile --rw-r--r-- 1 robert robert 898 16 sept. 19:39 _preamble_bbl.tex --rw-r--r-- 1 robert robert 699 14 sept. 15:02 _preamble-ed.tex --rw-r--r-- 1 robert robert 719 16 sept. 19:39 _preamble.tex --rw-r--r-- 1 robert robert 1407 17 sept. 00:15 README.md --rw-r--r-- 1 robert robert 1804 17 sept. 00:15 README.tex -[robert@kiddo courses]$ ./backup.sh - adding: sauvegarde/ (stored 0%) - adding: sauvegarde/README.tex (deflated 57%) - adding: sauvegarde/_preamble.tex (deflated 45%) - adding: sauvegarde/_preamble_bbl.tex (deflated 57%) - adding: sauvegarde/_preamble-ed.tex (deflated 44%) -[robert@kiddo courses]$ ls -l --color -total 44 --rwxr-xr-x 1 robert robert 82 17 sept. 22:06 |\textcolor{green}{backup.sh}| --rw-r--r-- 1 robert robert 165 16 sept. 19:40 bibliography.bib -drwxr-xr-x 5 robert robert 4096 17 sept. 22:31 |\textcolor{blue}{fichiers}| --rw-r--r-- 1 robert robert 680 16 sept. 18:34 makefile --rw-r--r-- 1 robert robert 898 16 sept. 19:39 _preamble_bbl.tex --rw-r--r-- 1 robert robert 699 14 sept. 15:02 _preamble-ed.tex --rw-r--r-- 1 robert robert 719 16 sept. 19:39 _preamble.tex --rw-r--r-- 1 robert robert 1407 17 sept. 00:15 README.md --rw-r--r-- 1 robert robert 1804 17 sept. 00:15 README.tex -drwxr-xr-x 2 robert robert 4096 17 sept. 22:31 |\textcolor{blue}{sauvegarde}| --rw-r--r-- 1 robert robert 2828 17 sept. 22:31 sauvegarde.zip -[robert@kiddo courses]$ ls sauvegarde -_preamble_bbl.tex _preamble-ed.tex _preamble.tex README.tex -\end{minted} -\begin{quoting} - \textbf{Commentaire:} - \begin{itemize} - \item lignes 1--11: la commande \commande{ls}\verb|ls -l --color| - donne l'état du dossier \emph{avant} l'exécution du script - \verb|backup.sh|; - \item lignes 12--17: exécution du script et messages du terminal; - \item lignes 18--30: la commande \verb|ls -l --color| donne l'état du - dossier \emph{après} l'exécution du script \verb|backup.sh|. On - voit qu'un nouveau répertoire \verb|sauvegarde| a été créé, de - même qu'un fichier archive \verb|sauvegarde.zip|; - \item lignes 31--32: la commande \verb|ls sauvegarde| liste le - contenu de ce répertoire. On y trouve tous les fichiers - \verb|.tex| qui y ont été copiés par le script. - \end{itemize} -\end{quoting} - -\paragraph{PATH} Un dernier point reste à éclaircir: à la ligne 12, -pourquoi a-t-on écrit \mintinline{bash}|./backup.sh| et non pas -simplement \mintinline{bash}|backup.sh|? Tout simplement pour des -raisons de sécurité. En effet, le principe est que les fichiers -exécutables se trouvent dans certains répertoires-système spécialement -conçus pour les accueillir. C'est pour cette raison que l'on peut -lancer les commandes \verb|bash| sans avoir à les préfixer. Or notre -répertoire de travail ne fait partie de ces répertoires spéciaux. Il -faut donc préfixer tout script exécutable qui s'y trouve par son -\emph{chemin d'accès}, soit relatif, soit absolu. On a choisi ici la -première méthode: dans la séquence \mintinline{text}|./|, le point -représente le répertoire courant tandis que le \emph{slash} précise -qu'il s'agit d'un chemin d'accès. Sans le \emph{slash}, le -\emph{shell} aurait compris le point comme un préfixe de fichier -caché. - -\section{Les variables} -\label{sec:les-variables} -Les variables sont des informations temporaires qui peuvent être -stockées et rappelées à tout moment. L'exemple qui suit va donner -l'occasion d'étudier une nouvelle commande, -\commande{echo}\verb|echo|, dont le rôle est justement de retourner -au terminal la chaîne de caractères qu'on lui passe en argument: -\begin{minted}[linenos]{text} -[robert@kiddo courses]$ mysystem="Linux" -[robert@kiddo courses]$ echo 'Mon système est $mysystem.' -Mon système est $mysystem. -[robert@kiddo courses]$ echo "Mon système est $mysystem." -Mon système est Linux. -\end{minted} - -\begin{quoting} - \textbf{Commentaire:} - \begin{description} - \item[Définition] Pour \emph{définir une variable}, on lui donne un - nom, suivi du signe $=$, suivi de sa définition entre guillemets - droits. - \item[Rappel] Pour \emph{rappeler} la valeur d'une variable, on - saisit le nom qu'on lui a donné, préfixé par le signe \verb|$|. - \end{description} - \begin{mdframed}[backgroundcolor=Cyan] - Observez la différence dans l'usage des guillemets! - \href{./01-ligne-de-commande.pdf#lnk_guillemets}{Comme - on le sait}, les guillemets servent à indiquer au \emph{shell} - que les espaces ne sont pas des caractères actifs. Il y a - cependant une grande différence entre les guillemets simples et - les guillemets doubles: les premiers renvoient une expression - littérale dans laquelle rien n'est interprété (lignes~2--3) tandis - que les seconds permettent l'interprétation des variables - (lignes~4--5). - \end{mdframed} -\end{quoting} - -Certaines variables sont automatiquement définies par \emph{bash}. Par -exemple: -\begin{enumerate} -\item \verb|$0|: renvoie le nom du script en cours d'exécution. -\item \verb|$1 - $9|: désignent les arguments successifs passés au - script. -\end{enumerate} - -Nous pouvons désormais perfectionner le script \verb|backup.sh|: -\begin{minted}[linenos]{bash} -#!/bin/bash -echo "Veuillez choisir l'extension des fichiers à sauvegarder" -echo "(sans le point):" -read -p 'extension: ' ext -echo "Veuillez choisir le nom du dossier de sauvegarde:" -read -p 'dossier: ' backupdir -mkdir "$backupdir" -cp *.$ext "$backupdir" -zip -r "$backupdir".zip "$backupdir" -echo "Terminé. $0 a copié vos fichiers .$ext dans $backupdir" -echo "et l'archive $backupdir.zip a été créée." -\end{minted} - -\paragraph{read} -\label{ref:read} -\commande*{read} Cette nouvelle commande est expliquée dans -le commentaire qui suit\footnote{Voir aussi plus loin - \vpageref{ref:read-plus}.}: -\begin{quoting} - \textbf{Commentaire:} - \begin{enumerate} - \item Une nouvelle commande a été introduite ici: aux lignes~4 et 6, - \verb|read| attend que l'utilisateur saisisse quelque chose au - clavier. Ensuite, la valeur saisie au clavier est associée à une - variable qui peut être reprise dans le script. On a également - passé à \verb|read| l'option \verb|-p| qui permet d'ajouter un - \emph{prompt} spécifique. - \item Aux lignes 7, 8 et 9, on a pris la précaution de mettre entre - guillemets doubles le rappel de la variable: - \verb|"$backupdir"|. On sait en effet que beaucoup d'utilisateurs - utilisent les espaces dans les noms des fichiers. Ici, la variable - étant rappelée à l'intérieur de guillemets doubles, elle sera - toujours interprétée correctement par \emph{bash}. - \end{enumerate} -\end{quoting} - -Exécution du script \verb|./backup.sh tex|: -\begin{minted}[linenos]{text} -[robert@kiddo courses]$ ./backup.sh -Veuillez choisir l'extension des fichiers à sauvegarder -(sans le point): -extension: tex -Veuillez choisir le nom du dossier de sauvegarde: -dossier: Houba - adding: Houba/ (stored 0%) - adding: Houba/README.tex (deflated 57%) - adding: Houba/_preamble.tex (deflated 45%) - adding: Houba/_preamble_bbl.tex (deflated 57%) - adding: Houba/_preamble-ed.tex (deflated 44%) -Terminé. ./backup.sh a copié vos fichiers .tex dans Houba -et l'archive Houba.zip a été créée. -\end{minted} -\begin{quoting} - \textbf{Commentaire:} - \begin{enumerate} - \item Les valeurs attendues ont été saisies par l'utilisateur aux - lignes~4 et 6. - \item À la ligne~12, le script a utilisé la variable \verb|$0| pour - retourner son propre nom. - \end{enumerate} -\end{quoting} - -\section{Captures et substitutions} -\label{sec:capt-et-subst} -Cette technique simple permet de transformer en variable le résultat -d'une commande. Il suffit de placer la commande entre parenthèses -précédées du signe $=$. Exemple: -\begin{minted}[linenos]{text} -[robert@kiddo courses]$ nbre=$(ls | wc -l) -[robert@kiddo courses]$ echo $nbre -8 -\end{minted} - -\needspace{2\baselineskip} -\begin{quoting} - \textbf{Commentaire:} - \begin{enumerate} - \item À la ligne~1, la commande \commande{ls}\verb|ls| liste les - fichiers, puis son résultat est interprété par - \commande{wc}\verb|wc -l| qui compte le nombre de fichiers - retournés. - \item La variable \verb|$nbre| contient donc ce dernier résultat. - \end{enumerate} -\end{quoting} - -Utilisons cette technique pour perfectionner notre script -\verb|backup.sh| (voir ci-dessous la ligne~9): -\begin{minted}[linenos]{bash} -#!/bin/bash -echo "Veuillez choisir l'extension des fichiers à sauvegarder" -echo "(sans le point):" -read -p 'extension: ' ext -echo "Veuillez choisir le nom du dossier de sauvegarde:" -read -p 'dossier: ' backupdir -mkdir "$backupdir" -cp *.$ext "$backupdir" -nbre=$(ls $backupdir/*.$ext | wc -l) -zip -r "$backupdir".zip "$backupdir" -echo "Terminé. $0 a copié $nbre fichiers .$ext dans $backupdir" -echo "et l'archive $backupdir.zip a été créée." -\end{minted} - -Exécution: -\begin{minted}[linenos]{text} -[robert@kiddo courses]$ ./backup.sh -Veuillez choisir l'extension des fichiers à sauvegarder -(sans le point): -extension: tex -Veuillez choisir le nom du dossier de sauvegarde: -dossier: Houba - adding: Houba/ (stored 0%) - adding: Houba/README.tex (deflated 57%) - adding: Houba/_preamble.tex (deflated 45%) - adding: Houba/_preamble_bbl.tex (deflated 57%) - adding: Houba/_preamble-ed.tex (deflated 44%) -Terminé. ./backup.sh a copié 4 fichiers .tex dans Houba -et l'archive Houba.zip a été créée. -\end{minted} - -\section{Conditions} -\label{sec:conditions} -Il est souvent très utile de n'exécuter des lignes de code que si -certaines conditions sont remplies. Reprenons ici l'exemple du script -\verb|backup.sh|: au moment où le script crée le répertoire de -sauvegarde, il ne contrôle pas si ce répertoire existe déjà, ce qui est -un défaut. Voici comment on peut créer une condition adaptée à cette -situation: -\begin{minted}[linenos]{bash} -if [ -d "$backupdir" ] -then - echo "Le dossier $backupdir existe déjà. Veuillez relancer le" - echo "programme et saisir un autre nom." - exit 1 -else - mkdir "$backupdir" -fi -\end{minted} -\begin{quoting} - \textbf{Commentaire:} - \begin{enumerate} - \item Observez la structure de la condition: - \begin{itemize} - \item ligne 1: \commande*{if}\mintinline{bash}|if| - $\rightarrow$ \emph{si } où la condition est posée - entre crochets. Dans l'expression entre les crochets, % - \verb|-d "$backupdir"|, \verb|-d| signifie: \verb|$backupdir| - existe \emph{et} est un répertoire; - \item ligne 2: \commande*{then}\mintinline{bash}|then| - $\rightarrow$ \emph{alors, passez à la ligne suivante}; - \item ligne 6: \commande*{else}\mintinline{bash}|else| - $\rightarrow$ \emph{autrement, passez à la ligne suivante}; - \item ligne 8: \commande*{fi}\mintinline{bash}|fi| - $\rightarrow$ \emph{fin de la condition} (en fait les deux - lettres de la conjonction \verb|if| écrite à l'envers). - \end{itemize} - \item À la ligne 5, la commande \commande{exit}\verb|exit 1| - ordonne au programme de se terminer immédiatement et de renvoyer - la valeur \verb|1| comme numéro d'état (\emph{status number}). Par - convention, \verb|0| est pour \emph{true} (le programme a bien été - exécuté) et \verb|1| est pour \emph{false} (il y a eu une erreur). - \end{enumerate} -\end{quoting} - -Voici donc comment se présente le script \verb|backup.sh| une fois la -condition insérée: -\captionof{listing}{bash: exemple de condition \texttt{if-then-else}% -\label{lst:if-then-else}} -\inputfile[linenos,highlightlines={7-14}]{bash}{backup.sh} - -\subsection{Conditions en série} -\label{sec:conditions-en-serie} -Supposons que le répertoire de sauvegarde ait été supprimé mais que -l'archive \verb|.zip| correspondante ne l'ait pas été. Dans ce cas, le -script \verb|backup.sh| l'écraserait. Pour éviter cela, nous pouvons -utiliser dans le script l'instruction -\commande*{elif}\verb|elif| qui permet de construire des -conditions en série. Littéralement, \verb|elif| est pour \emph{else - if}, \enquote{ou autrement, si\ldots}. Voici donc ce qu'il faut -ajouter: -\begin{minted}{bash} -elif [ -e "$backupdir".zip ] - then - echo "L'archive $backupdir.zip existe déjà. Veuillez la supprimer" - echo "ou la déplacer en dehors de ce dossier, puis relancez le" - echo "programme." - exit 1 -\end{minted} - -Ce qui donne le script \verb|backup-mk2.sh| suivant: -\captionof{listing}{bash: instruction \texttt{elif}\label{lst:elif}} -\inputfile[linenos,highlightlines={12-17}]{bash}{backup-mk2.sh} - -\subsection{Tests} -\label{sec:tests} -Le tableau suivant donne la liste des tests les plus répandus que l'on -peut associer aux conditions. Les tests sont placés entre crochets -droits comme le montre la ligne~7 du \vref{lst:if-then-else}. -\begin{xltabular}{.77\linewidth}{lX} - \toprule - Opérateur & Description \\ - \midrule\endhead - \verb|! expr| & \verb|expr| est faux \\ - \verb|-n str| & la longueur de \verb|str| $>0$\footnote{Comprendre: - \texttt{str} existe.} \\ - \verb|-z str| & la longueur de \verb|str| $=0$\footnote{Comprendre: - \texttt{str} n'existe pas.}\\ - \verb|str1 = str2| & \verb|str1| est égal à \verb|str2|\\ - \verb|str1 != str2| & \verb|str1| n'est pas égal à \verb|str2|\\ - \verb|int1 -eq int2| & les nombres \verb|int1| et \verb|int2| sont - égaux\\ - \verb|int1 -gt int2| & \verb|int1| $>$ \verb|int2|\\ - \verb|int1 -lt int2| & \verb|int1| $<$ \verb|int2|\\ - \verb|-d fichier| & \verb|fichier| existe et est un répertoire\\ - \verb|-e fichier| & \verb|fichier| existe \\ - \verb|-s fichier| & \verb|fichier| existe et n'est pas vide (taille - $>0$) \\ - \verb|-r fichier| & \verb|fichier| existe et est accessible en - lecture\\ - \verb|-w fichier| & \verb|fichier| existe et est accessible en - écriture \\ - \verb|-x fichier| & \verb|fichier| existe et est accessible en - exécution \\ - \bottomrule - \caption{tests\label{tab:tests}} - \label{tab:tests} -\end{xltabular} - -\paragraph{test} -\commande*{test} À l'intérieur du script \verb|bash|, les -crochets renvoient en fait à une commande par ailleurs disponible: -\verb|test|. La commande \verb|test| renvoie en fait la sortie -\verb|0| si le résultat est \emph{vrai} et \verb|1| si le résultat est -\emph{faux}. Le terminal ne retourne pas le resultat, mais celui-ci -est associé à une variable -\verb|$?| que l'on peut afficher par la commande: -\commande{echo}\mintinline{bash}|echo $?|. En voici quelques -exemples: -\begin{minted}[linenos]{text} -[robert@kiddo courses]$ ls -bibliography.bib makefile _preamble-ed.tex _preamble.tex README.tex -fichiers _preamble_bbl.tex _preamble.log README.md -[robert@kiddo courses]$ test -d fichiers -[robert@kiddo courses]$ echo $? -0 -[robert@kiddo courses]$ test -x makefile -[robert@kiddo courses]$ echo $? -1 -[robert@kiddo courses]$ test -e makefile -[robert@kiddo courses]$ echo $? -0 -[robert@kiddo courses]$ test 0123 = 123 -[robert@kiddo courses]$ echo $? -1 -[robert@kiddo courses]$ test 0123 -eq 123 -[robert@kiddo courses]$ echo $? -0 -\end{minted} -\begin{quoting} - \textbf{Commentaire ---} Cet exemple montre quelle est la différence - entre le test $=$ pour qui il faut une stricte équivalence dans les - chaînes de caractères, et le test \verb|-eq| qui est un test - arithmétique. -\end{quoting} - -\subsection{Indentation} -\label{sec:indentation} -L'indentation est une technique qui consiste à donner aux lignes de -code différentes profondeurs de marge à gauche de façon à distinguer -clairement des blocs logiques. Les lignes 7--20 du -\vref{lst:if-then-else} en donnent un exemple. L'indentation permet de -faire apparaître clairement ce qui dépend de l'instruction -\commande{if}\verb|if| (l.~7), puis \commande{elif}\verb|elif| -(l.~12) et enfin \commande{else}\verb|else| (l.~18). - -Cette technique est commune à tous les langages informatiques et tous -les programmeurs l'utilisent. En Python, que nous étudierons plus -tard, l'indendation fait même partie du langage lui-même, puisque -Python a recours à l'indentation pour structurer les blocs logiques, à -la différence d'autres langages qui ont recours soit à des -déclarations explicites telles que \verb|begin ... end| ou encore à -des opérateurs tels que \verb|{ ... }| - -Voici un exemple d'indentation d'une structure dans laquelle on a -placé une condition à l'intérieur d'une autre condition: -\captionof{listing}{bash: exemple d'indentation} -\inputfile[linenos]{bash}{greaterthan.sh} - -\subsection{Opérateurs booléens} -\label{sec:operateurs-booleens} -Les opérateurs booléens, dont le nom est tiré du mathématicien anglais -George Boole, sont des opérateurs logiques que l'on peut associer à -des conditions. En voici deux ici: -\begin{enumerate} -\item \verb+||+ pour \emph{ou}; -\item \verb|&&| pour \emph{et}. -\end{enumerate} - -Par exemple, dans le \vref{lst:elif} ci-dessus, on pourrait remplacer -les lignes 7--20 par le code ci-dessous: -\begin{minted}[linenos]{bash} -if [ -d "$backupdir" ] || [ -e "$backupdir".zip ] - then - echo "Le dossier $backupdir et/ou l'archive $backupdir.zip" - echo "existent déjà. Veuillez relancer le programme et saisir" - echo "un autre nom." - exit 1 -else - mkdir "$backupdir" -fi -\end{minted} - -\subsection{case} -\label{sec:case}\commande*{case} -\verb|case| est une instruction qui permet d'exécuter différentes -actions en fonction de la valeur d'une variable. Elle est intéressante -à étudier ici car elle fait appel à la fois à la notion de variable et -aux expressions régulières. La syntaxe est la suivante: -\begin{minted}[linenos]{bash} -case $var in - expr1) - - ;; - expr2) - - ;; -esac -\end{minted} -\begin{quoting} - \textbf{Commentaire:} - \begin{enumerate} - \item L'instruction \verb|case| se termine par \verb|esac|, de même, - comme on l'a vu, que l'expression \verb|if| se termine par - \verb|fi|. - \item Les expressions régulières sont suivies d'une parenthèse - fermante. - \item Pour passer d'un jeu de commande au jeu suivant, on écrit, sur - une ligne \verb|;;| - \end{enumerate} -\end{quoting} - -Le \vref{lst:case} montre un exemple facile à comprendre de cette -technique. -\captionof{listing}{bash: instruction \texttt{case}\label{lst:case}} -\inputfile[linenos]{bash}{animal.sh} -\begin{quoting} - \textbf{Commentaire:} - \begin{enumerate} - \item À la ligne 4, l'utilisateur est invité à entrer une - réponse. L'instruction \commande{read}\verb|read| associe la - réponse à la variable \verb|animal|. - \item À la ligne 6, l'instruction \verb|case| reprend la variable - qui est donc préfixée par le signe \verb|$|. - \item Aux lignes 7 et 10, on permet à l'utilisateur d'entrer soit le - mot \emph{chien}, soit le mot \emph{chat}. L'initiale peut être - une minuscule ou une majuscule. - \item À la ligne 13, comme le signe \verb|*| est en \emph{bash} le - \emph{wildcard} qui représente toute séquence de caractères, la - commande de la ligne~14 sera forcément exécutée si les tests des - lignes~7 et~10 ont échoué. - \end{enumerate} -\end{quoting} - -\begin{quoting} - \textbf{Remarque:} à la place de l'instruction \verb|case|, on - recommande aujourd'hui d'utiliser une nouvelle instruction, - \commande{switch}\verb|switch|, dont la syntaxe, plus complexe, - n'est pas étudiée ici. -\end{quoting} - -\section{Boucles} -\label{sec:boucles} -Les boucles (en anglais: \emph{loops}) servent à indiquer qu'une série -d'instructions doit reprendre et continuer à s'exécuter aussi -longtemps qu'une condition donnée est remplie ou n'est pas remplie. - -Prenons un exemple simple. Nous avons dans un répertoire plusieurs -centaines d'images de différents formats et nous souhaitons convertir -au format \verb|.png| toutes les images qui sont enregistrées au -format \verb|.tiff|. - -Pour convertir une seule image, nous pouvons utiliser l'outil en ligne -de commande \verb|convert| fourni par le programme -\emph{imagemagick}\footnote{\url{http://www.imagemagick.org}}. Pour -convertir une seule image, la syntaxe est la suivante: -\begin{minted}{bash} -convert image.tiff image.png -\end{minted} - -Mais comment faire pour en convertir un grand nombre pris dans un -répertoire qui en compte des centaines enregistrées dans des formats -différents? - -\paragraph{basename} -\commande*{basename}Avant de continuer, il faut dire un mot de la -commande \verb|basename| que nous allons utiliser ici. Cette commande -permet de dépouiller un nom de fichier de son chemin d'accès et de son -extension. La syntaxe est la suivante: -\begin{minted}[escapeinside=||]{text} -basename -s .|\emph{ext}| |\emph{file}| -\end{minted} -où \emph{ext} est le nom de l'extension et \emph{file} le nom du -fichier. Voici un exemple: -\begin{minted}{text} -[robert@kiddo fichiers]$ ls -l images/ -total 252 --rw-r--r-- 1 robert robert 96404 2 juil. 18:32 02-ascii.png --rw-r--r-- 1 robert robert 33951 20 juin 19:59 02-donnees1.png --rw-r--r-- 1 robert robert 11503 20 juin 20:01 02-donnees2.png --rw-r--r-- 1 robert robert 17450 3 juil. 17:43 02-exercice_formats.png --rw-r--r-- 1 robert robert 87510 14 sept. 15:06 02-unicode.png -[robert@kiddo fichiers]$ basename -s .png images/* -02-ascii -02-donnees1 -02-donnees2 -02-exercice_formats -02-unicode -\end{minted} - -\paragraph{for-do-done} -\commande*{for}\commande*{do}\commande*{done} -La boucle que nous allons utiliser fait appel à trois instructions: -\begin{enumerate} -\item \verb|for| prend comme argument un nom qui sera ensuite traité - comme une variable. Le nom de la variable est suivi de l'instruction - \commande{in}\verb|in| et d'un nom de fichier qui contient des - données séparées par des espaces ou bien d'une expression dans - laquelle on a placé des - \href{./01-ligne-de-commande.pdf#lnk_wildcards}{\emph{wildcards}}. -\item \verb|do| est suivi des commandes qu'il faut exécuter sur chaque - élément retourné par l'instruction \verb|for| \ldots{} \verb|in|. -\item \verb|done| marque la fin de la boucle. -\end{enumerate} - -Voici maintenant le script qui assure la conversion du format -\verb|.tiff| vers le format \verb|.png|: -\captionof{listing}{bash: \texttt{for ... do ... done}} -\inputfile[linenos]{bash}{tiff2png.sh} - -\begin{quoting} - \textbf{Commentaire:} - \begin{enumerate} - \item Comprendre ainsi le début de la ligne~2 % - (\mintinline{bash}|for file in|): \enquote{pour tout \texttt{file} - dans\ldots} où \verb|file| définit une variable dont la valeur - pourra ensuite être rappelée par \verb|$file|. Le reste de la - ligne est une \emph{double capture} (v.~\emph{supra}, - \vref{sec:capt-et-subst}): - \begin{enumerate} - \item \verb|$(ls *.tiff)| liste et retourne tous les fichiers dont - l'extension est \verb|.tiff| - \item \verb|$(basename -s .tiff $(ls *.tiff))| demande à - \verb|basename| de dépouiller tous ces fichiers de leur - extension \verb|.tiff| et retourne la liste des noms seuls. - \end{enumerate} - \item La variable \verb|file| est donc une liste constituée des noms - de tous les fichiers \verb|.tiff| sans leur extension. La ligne~3 - les convertit tous les uns après les autres vers le format - \verb|.png|. - \end{enumerate} -\end{quoting} - -\paragraph{while} -\commande*{while} L'expression \verb|while| exécute les -lignes de code qui suivent aussi longtemps qu'un test donné retourne -un résultat positif (\enquote{vrai}, en anglais \emph{true}). Le -script \verb|countlines.sh|, donné dans le \cref{lst:countlines} -ci-dessous, utilise cette expression pour compter les lignes des -fichiers\footnote{Pour une autre façon plus simple d'écrire le même - programme, voir le \vref{lst:countlines-mk2}.}. -\captionof{listing}{bash: \texttt{while}\label{lst:countlines}} -\inputfile[linenos,highlightlines={13,16-17}]{bash}{countlines.sh} - -\paragraph{read} -\label{ref:read-plus}\commande*{read} -On a déjà présenté plus haut \vpageref{ref:read} cette -instruction. Pour bien comprendre le \cref{lst:countlines}, il faut -savoir que la fonction de \verb|read| est de \emph{lire une ligne}, -quelle que soit cette ligne, depuis l'entrée standard du \emph{shell} -(en anglais: \emph{standard input}). Dans le \vref{lst:case}, la ligne -en question était donc constituée d'une saisie au clavier dans -laquelle la ligne était formée par une chaîne de caractères terminée -par un \emph{retour charriot} (\emph{carriage return}). - -\begin{mdframed}[backgroundcolor=Cyan] - \verb|read| admet aussi une option \verb|-r| qui est importante: - quand cette option est activée, le caractère \verb|\| - (\emph{backslash}) est traité comme un caractère ordinaire, et non - comme un caractère actif. Pour simplement compter les lignes d'un - fichier, il faut ajouter cette option car en \emph{bash} le - \emph{backslash} est précisément un caractère actif: à la fin d'une - ligne, il sert à joindre cette ligne à la ligne suivante. -\end{mdframed} - -Étudions de près les lignes~13--17 du \cref{lst:countlines}: -l'instruction \verb|while| (l.~13) se termine à la ligne~17 par -\verb|done|. Et aussitôt à ce moment, -\href{./01-ligne-de-commande.pdf#lnk_redirection}{l'opérateur - de redirection} \mintinline{bash}|<| lit le contenu du fichier dont -le nom correspond à la variable \verb|file| et le passe en argument à -la boucle \verb|while ... done|. - -\paragraph{Commentaire du \cref{lst:countlines}} -\begin{enumerate} -\item À la ligne~6, on crée une variable \verb|numline| à laquelle - on attribue la valeur \verb|0|. Elle servira donc de compteur. -\item L'instruction essentielle est à la ligne~13: - \mintinline{bash}|while read -r line|: comme ce qui suit - \verb|while| \emph{est un test}, ce test donnera un résultat positif - aussi longtemps que la variable \verb|line| existe, c'est-à-dire - aussi longtemps que l'opérateur de redirection \mintinline{bash}|<| - de la ligne~17 envoie des lignes terminées par un retour - charriot. Tant que cette condition est remplie, la commande de la - ligne~16 sera exécutée, et le compteur de lignes sera incrémenté - d'une unité à chaque fois. -\item Les instructions des lignes~20--25 sont faciles à - suivre. Étudiez-les à l'aide du \vref{tab:tests}: vous pourrez - comprendre comment la programmation peut être adaptée pour suivre - les règles de l'orthographe française. -\end{enumerate} - -Exécutons maintenant le script: -\begin{minted}{text} -[robert@kiddo courses]$ ./countlines.sh -Entrez le nom du fichier dont vous voulez compter les lignes: -Fichier: whack -Erreur: le fichier whack n'existe pas. -[robert@kiddo courses]$ ./countlines.sh -Entrez le nom du fichier dont vous voulez compter les lignes: -Fichier: makefile -Votre fichier makefile compte 21 lignes. -\end{minted} - -\paragraph{until} -\commande*{until}À la différence de \verb|while|, -\verb|until| exécute les instructions qui suivent jusqu'au moment où -le résultat du test associé à \verb|until| devient \emph{positif} -(\emph{true}). Pour prendre un exemple très simple, le script suivant, -que l'on appellera \verb|rah.sh|, demande combien de fois on souhaite -tirer la queue d'un lion: -\captionof{listing}{bash: comment faire rugir le lion?} -\inputfile[linenos]{bash}{rah.sh} - -\begin{quoting} - \textbf{Commentaire:} - \begin{enumerate} - \item La condition posée à la ligne~17 se comprend ainsi: - \enquote{faites ce qui suit jusqu'à ce que le compteur de - rugissements atteigne une valeur supérieure à celle définie par - l'utilisateur. Si la valeur est supérieure, sortez de la boucle.} -\item À la ligne~20, on demande à \emph{bash} d'attendre une seconde. -\item À la ligne~21, on incrémente de 1 la valeur du compteur de - rugissements (voir ci-dessus le \vref{lst:countlines}, l.~14), puis - on reprend la boucle à la ligne~17. - \end{enumerate} -\end{quoting} - -Exécution du script \verb|rah.sh|: -\begin{minted}{text} -[robert@kiddo courses]$ ./rah.sh -Combien de fois tirez-vous la queue du lion? 3 -Raaaaaaaaahhhhhhhhhhhh! (1) -Raaaaaaaaahhhhhhhhhhhh! (2) -Raaaaaaaaahhhhhhhhhhhh! (3) -[robert@kiddo courses]$ -\end{minted} - -\paragraph{break} -\commande*{break} \verb|break| est une instruction qui -ordonne de quitter immédiatement la boucle dans laquelle on se -trouve. Supposons par exemple que l'on écrive un programme dans lequel -on souhaite limiter une action telle que la copie de -fichiers. L'instruction \verb|break| sera exécutée dès que la limite -est atteinte. Appelons ce script \verb|copyten.sh|: -\captionof{listing}{bash: copie d'un nombre limité de - fichiers\label{lst:copyten}} -\inputfile[linenos]{bash}{copyten.sh} - -Ce script donne un exemple de code commenté. Comme on le voit, les -commentaires peuvent se trouver sur des lignes isolées aussi bien que -sur des lignes qui contiennent des commandes\footnote{Voir ci-dessus, - \vref{sec:les-commentaires}.}. - -Exécution du script \verb|copyten.sh|: -\begin{minted}{text} -[robert@kiddo courses]$ ls *.txt -01.txt 03.txt 05.txt 07.txt 09.txt 11.txt -02.txt 04.txt 06.txt 08.txt 10.txt 12.txt -[robert@kiddo courses]$ ./copyten.sh -Attention: ce programme copie au maximum 10 fichiers. -Que souhaitez-vous copier: *.txt -Répertoire de destination: Houba -Erreur: la destination doit être un répertoire. - Le cas échéant, utilisez "mkdir Houba" - pour créer le répertoire de destination. -[robert@kiddo courses]$ mkdir Houba -[robert@kiddo courses]$ ./copyten.sh -Attention: ce programme copie au maximum 10 fichiers. -Que souhaitez-vous copier: *.txt -Répertoire de destination: Houba -Terminé. 10 fichiers au maximum ont été copiés dans Houba. -[robert@kiddo courses]$ ls Houba/ -01.txt 02.txt 03.txt 04.txt 05.txt 06.txt 07.txt -08.txt 09.txt 10.txt -\end{minted} - -\paragraph{continue} -\commande*{continue} À l'inverse de \verb|break|, -\verb|continue| demande à \emph{bash} d'interrompre l'itération -courante mais sans quitter la boucle, puis de reprendre la boucle à -partir de l'itération suivante. C'est une façon de prévoir des -exceptions. Par exemple, nous pouvons modifier le script -\ref{lst:copyten} comme suit: - -\captionof{listing}{bash: copie d'un nombre limité de - fichiers sans échec si le fichier source n'existe pas} -\inputfile[linenos,highlightlines={26-31}]{bash}{copyten-mk2.sh} - -\begin{quoting} - \textbf{Commentaire:} - \begin{enumerate} - \item À la ligne~30, l'instruction \verb|continue| intervient dans - le cas où le fichier à copier n'existe pas (voir le test de la - ligne~26). - \item Dans ce cas, le fichier est créé par la ligne~28. - \item Puis \verb|continue| interrompt la boucle et la reprend depuis - la ligne~24. - \end{enumerate} -\end{quoting} - -Voici ce que donne l'exécution de ce script: -\begin{minted}{text} -[robert@kiddo courses]$ ./copyten-mk2.sh -Attention: ce programme copie au maximum 10 fichiers. -Que souhaitez-vous copier: tchic.txt -Répertoire de destination: Houba -création de tchic.txt qui n'existe pas... -Terminé. 10 fichiers au maximum ont été copiés dans Houba. -[robert@kiddo courses]$ ls Houba/ -tchic.txt -\end{minted} - -\section{Les fonctions} -\label{sec:les-fonctions} -Comme leur nom l'indique, les fonctions permettent d'exécuter des -instructions de façon autonome dans un script. Elles peuvent être -ensuite utilisées aussi souvent que nécessaire et permettent donc de -réduire la taille du script. Deux formats sont permis: -\begin{minted}[linenos]{bash} -# Format 1 -ma_fonction () { - -} - -# Format 2 -function ma_fonction { - -} -\end{minted} - -Ces deux formats sont strictement équivalents. Le premier est le plus -répandu car il rappelle ce qui se fait dans de nombreux autres -langages où l'on utilise les parenthèses pour passer aux fonctions des -variables, des chaînes de caractères, des paramètres optionnels ou -même d'autres fonctions. Toutefois, en \emph{bash}, on ne met jamais -rien entre les parenthèses qui sont purement décoratives. - -Le script suivant permet de parvenir au même résultat que le script -qui a été présenté dans le \vref{lst:countlines}: -\captionof{listing}{bash: exemple de - fonction\label{lst:countlines-mk2}} -\inputfile[linenos]{bash}{countlines-mk2.sh} - -Pour terminer, exécutons cette nouvelle version de notre script -ici appelée \verb|countlines-mk2.sh|: - -\begin{minted}{text} -[robert@kiddo courses]$ ./countlines-mk2.sh -Entrez le nom du fichier dont vous voulez compter les lignes: -Fichier: makefile -Votre fichier makefile compte 21 lignes. -\end{minted} - -\printindex[cmds] -\end{document} diff --git a/fichiers/03-tableur_bdd.tex b/fichiers/03-tableur_bdd.tex new file mode 100644 index 0000000..c20d990 --- /dev/null +++ b/fichiers/03-tableur_bdd.tex @@ -0,0 +1,405 @@ +\input{../_preamble-ed.tex} +\usepackage{comment} + +\usepackage[toc]{multitoc} +\usepackage{graphicx} +\graphicspath{{images/}} + +\title{Tableur et base de données} + +\usepackage{hyperref} + +\begin{document} +\maketitle +\renewcommand{\contentsname}{Sommaire} +\tableofcontents + +\chapter{Qu'est-ce qu'une donnée?} + +\section{Définitions} +Une donnée est un élément brut, qui n'a pas encore été interprété, mis +en contexte. La mise en contexte crée de la valeur ajoutée pour +constituer une information (on peut définir l'information comme +l'interprétation d'une source de données). Les données brutes peuvent +être entrées dans un programme informatique ou utilisées dans des +procédures manuelles comme l'analyse statistique d'une enquête par +exemple. + +Qu'entend-on maintenant par \enquote{données publiques}? Ce sont les +données qui figurent dans les documents communiqués ou publiés par les +administrations. À partir de là, quand on parle d'\emph{open data}, il +s'agit de la mise à disposition de tous les citoyens sur internet des +données publiques ayant vocation à être librement accessibles et +gratuitement réutilisables. Ces données sont diffusées de manière +structurée selon une licence ouverte garantissant leur libre accès et +leur réutilisation par tous, sans restriction technique, juridique ou +financière. Cela signifie que n'importe quel utilisateur peut utiliser +ces données, les modifier ou les partager (même à des fins +commerciales). + +Il y a enfin une autre expression que vous avez certainement +entendues: celle de \emph{big data} qui désigne littéralement les +\enquote{grosses données}. Qu'entend-on par là? Les vibrations de tel +tablier de pont, les sentiments exprimés sur tel réseau social, les +achats ou recherches sur tel site… Toutes ces données, utiles pour la +maîtrise de machines ou notre vie sociale, économique, voire +sentimentale, laissent des traces, des scories, qui sont de plus en +plus souvent conservées. C’est de cette profusion de données sur de +nombreux domaines que résultent les Big Data ou mégadonnées. On le +voit, ces Big Data désignent des ensembles de données tellement +volumineux qu'il devient difficile, voire impossible, de les manipuler +avec des outils classiques de gestion de base de données ou de gestion +de l'information. + + +\section{Formats} En fonction de ce que l'on veut faire, les +données informatiques sont rangées dans des fichiers. Le choix de la +méthode de rangement, c'est ce qu'on appelle le format. Pour +l'utilisateur, le format est représenté par une extension. Le format +est déterminé par le logiciel au moment de l'enregistrement d'un +document. Comme vous l'avez certainement constaté, le système associe +par défaut un logiciel à un format, raison pour laquelle, quand vous +double-cliquez sur un document, il s'ouvre automatiquement sans que +vous ayez à préciser quel logiciel doit l'ouvrir. Avant de vous +présenter les différents formats que vous devez connaître, sachez que +chaque format relève d'une logique, d'une structure. On en distingue +trois. + + +\paragraph{les principales structures utilisées}: voici les trois +principales structures utilisées pour présenter les données: +\begin{enumerate} +\item la structure tabulaire: c'est la plus répandue. On organise les +données dans des colonnes et des lignes. Voir par exemple les données +concernant la fréquentation des musées italiens: +\url{http://www.datiopen.it/opendata/Visitatori_musei_pubblici_e_similari_titolo_d_accesso#ui-tabs-3}. Un +des formats qui relève de cette structure est le format csv +(Comma-separated values); il permet d'organiser des données en +cellules afin qu'elles soient traitées par un tableur ou insérées dans +une base de données. Les données dans un document csv sont le plus +souvent encadrées par des guillemets et séparées par des points +virgule. + +\begin{figure}[h] \centering \includegraphics[scale=0.6]{03-donnees2.png} +\end{figure} + +\item la structure hiérarchique: les données présentées ainsi montrent +les rapports entre les points de données comme pour un arbre +généalogique. + +\item la structure en réseau: les données structurées ainsi permettent +des rapports entre n'importe quelle combinaison d'éléments dans +n'importe quelle direction. Le web en est un bon exemple puisque les +pages web comportent des liens vers un nombre incalculable d'autres +pages. Cf. le format xml (Extensible Markup Language) qui a pour +objectif de faciliter l'échange automatisé de contenus complexes. Un +document xml est constitué d'un prologue qui indique les informations +de traitement (comme le jeu de caractères utilisé), et du corps du +document, constitué d'un ensemble de balises qui décrivent les données +(se présentant sous la forme d'une arborescence). Où trouve-t-on du +xml? Dans les pages web, les documents OpenOffice sont également des +fichiers xml, les logiciels de dessin comme InkScape utilisent aussi +ce format, etc. + +\begin{figure}[h] \centering \includegraphics[scale=0.6]{03-donnees1.png} +\end{figure} + +NB: vous remarquerez que les mêmes données peuvent être présentées +sous des formats différents. +\end{enumerate} + +\paragraph{les formats que vous devez savoir utiliser}: on distingue +les formats ouverts dont les spécifications sont publiquement +accessibles des formats fermés qui sont souvent propriétaires (même +quand un format propriétaire est ouvert, les entreprises qui le +commercialisent tentent d'en conserver le contrôle en proposant de +nouvelles versions plus élaborées ou en ayant recours aux +brevets). Voici la liste des principaux formats que vous +rencontrerez. Vous penserez à préciser quels sont ceux qui sont +ouverts. + +\begin{figure}[h] \centering +\includegraphics[scale=0.6]{03-exercice_formats.png} +\end{figure} + +Sur le format txt: éditeur de textes et traitement de +textes. Qu’est-ce qu’un éditeur de textes ? À quoi cela sert-il ? +Est-ce la même chose qu’un traitement de texte ? Un éditeur de texte +est un programme qui permet de modifier des fichiers de texte brut, +sans mise en forme (gras, italique, souligné…). Sous Windows, on +dispose d’un éditeur de texte très basique, le Bloc-Notes, mais il +existe aussi NotePad++ (plus évolué). Sous Linux, on a le choix entre +Nano, Vim, Emacs, et bien d’autres. Un traitement de texte, en +revanche, est fait pour rédiger des documents mis en forme. Word et +LibreOffice Writer sont certainement les plus célèbres. + + +\paragraph{Exercice 1} + +Quand a-t-on besoin d’un éditeur de texte ? Chaque fois qu’on veut +éditer un fichier de texte brut (au format .txt). Si les éditeurs de +texte sont parfaits pour les programmeurs, ils sont aussi utiles pour +retravailler du texte à l’aide de commandes puissantes, avant de le +structurer dans un traitement de textes. Exemple : quand on récupère +une œuvre ou un extrait d’œuvre depuis une bibliothèque numérique, il +faut très souvent supprimer les retours à la ligne intempestifs qu’on +appelle hard wrap. Il est très facile de le faire grâce à un éditeur +comme Notepad++ : allez dans le menu TextFX, commande TextFXEdit, +sous-commande Unwrap Text. Les retours à la ligne simples sont +convertis en fin de ligne (mode soft wrap) tandis que les doubles +retours subsistent. À ce problème, s’ajoute parfois aussi celui de +caractères cabalistiques qui apparaissent à la place des caractères +accentués. + +\paragraph{Exercice 2} +\begin{enumerate} +\item Récupérez au format txt sur Gutenberg \emph{Le corbeau} de Poe +et ouvrez-le dans LibreOffice ; +\item Faites apparaître au début du document le titre de l’œuvre en +italique (comme il se doit), puis enregistrez ce fichier au format +natif d’OO (.odt). Enregistrez maintenant ce fichier au format txt et +ouvrez-le avec un éditeur de textes par exemple : commentez la +différence ; +\item Exportez-le enfin au format pdf et veillez à ce que l’ouverture +de ce fichier soit protégé par un mot de passe que vous définirez. +\end{enumerate} + + +\section{Le problème des données textuelles: coder du texte} +\paragraph{Encodage binaire} +C'est dans les années 60 qu'apparaît la +nécessité de représenter chaque caractère en code traitable par +l'ordinateur. Or la mémoire d'un ordinateur n'est capable +d'enregistrer qu'une suite de 0 et 1 (encodage binaire): à l'origine, +les lettres de l'alphabet ont donc été encodées sous la forme d'une +suite de 0 et de 1. + + +\paragraph{La table ASCII} Mais de quel alphabet parle-t-on? Tout +commence par une constatation très simple : les premiers +informaticiens parlaient anglais. Et l’anglais s’écrit avec peu de +choses : deux fois 26 lettres, 10 chiffres, une trentaine de signes de +ponctuation, de signes mathématiques, sans oublier le symbole +dollar. : avec 95 caractères au total on peut se débrouiller. À +l’époque dont je parle, on ne pouvait utiliser que la moitié des +octets, soit 128 valeurs. On en a pris 33 comme caractères de « +contrôle » (comme le retour à la ligne par exemple), plus les 95 dont +on avait besoin pour écrire l’anglais. On a donc attribué des numéros +à toutes ces valeurs : le code ASCII (American Standard Code for +Information Interchange) était né. Voir la figure \ref{ascii}. + +\begin{figure}[h] \centering \includegraphics[scale=0.5]{03-ascii.png} +\caption{La table ASCII} +\label{ascii} +\end{figure} + + +\paragraph{L'unicode} Mais au bout d’un certain temps est apparue la +nécessité de taper du français ou de l’allemand: on a donc utilisé les +valeurs laissées de côté par l’ASCII et il a été possible de caser les +caractères accentués et divers autres symboles utilisés par les +langues d’Europe de l’ouest. Dans ces 128 valeurs, il n’y a hélas pas +eu de place pour les caractères des langues occidentales et l’alphabet +cyrillique et l’alphabet grec et l’alphabet hébreu. Pour pouvoir +taper plusieurs langues sur un même ordinateur et pour que les +ordinateurs puissent communiquer entre eux, des organismes de +standardisation ont créé des tables de correspondance, comme +l’ISO-8859-1, qui propose un jeu de caractères pour les langues +occidentales, l’ISO-8859-5 qui offre du cyrillique, l’ISO-8859-7, qui +propose du grec, etc. Mais, malgré tout, il n’a pas été possible de +faire rentrer les 1945 idéogrammes du japonais officiel dans un octet, +ni les 11 172 syllabes coréennes, ni les dizaines de milliers +d’idéogrammes chinois qu’on arrive à recenser... Pour résoudre +durablement tous ces problèmes de langues, au début des années 2000, +s’est formé un consortium regroupant des grands noms de l’informatique +et de la linguistique : le consortium Unicode. Sa tâche : recenser et +numéroter tous les caractères existant dans toutes les langues du +monde. Est donc né un jeu universel de caractères, acceptant plusieurs +encodages, l’unicode. En 2007, le standard publié comportait environ +60 000 caractères. Prenons, par exemple, le sigma majuscule: il a été +encodé avec le point de code \texttt{U+03A3} (voir la figure +\ref{unicode}). + +Mais l'unicode prend beaucoup plus de place que l'ASCII. Or, pour +prendre l'exemple du français, la grand majorité des caractères +utilisent seulement le code ASCII. On a donc imaginé l'UTF-8 (Unicode +Transformation Format): un texte en UTF-8 est partout en ASCII et dès +qu'on a besoin d'un caractère appartenant à l'unicode on utilise un +caractère spécial pour l'indiquer. + + +\begin{figure}[h] \centering \includegraphics[scale=0.7]{03-unicode.png} +\caption{Aperçu de la table de codage unicode pour l'alphabet grec} +\label{unicode} +\end{figure} + +Cela dit, comment faire pour saisir une citation en espagnol, chinois, +arabe ou grec ancien au milieu d’un texte en français ? Il faut non +seulement disposer d’une police unicode (comme Gentium), mais encore +d’un clavier virtuel qui vous permet de savoir où se trouvent les +caractères. Ainsi, pour être en mesure de saisir du texte dans une +langue autre que le français, vous devez attribuer à votre clavier la +langue de saisie souhaitée. Par exemple, pour taper οὐκ ἔλαβον πόλιν, +vous devez configurer votre clavier de façon à saisir π quand vous +tapez sur la touche P. Pour ce faire, il suffit de cliquer du droit +sur l’icône FR, puis de choisir «~Paramètres~» et «~Ajouter~». Il +vous est aussi possible d’utiliser des claviers virtuels en ligne, +comme celui disponible à l’adresse suivante : +http://www.lexilogos.com/clavier/multilingue.htm + +\section{Coder des images} Une image se décompose en points appelés +pixels (premier critère de qualité d'une image). À chaque pixel est +associée une couleur décomposée en trois composantes, rouge, vert et +bleu, chacune étant notée par un nombre entre 0 et 255. Exemple: le +code pour le bleu ciel est (119, 181, 254), chaque nombre représentant +le dosage nécessaire de chacune des couleurs primaires pour obtenir la +couleur désirée. C'est ce qu'on appelle le code RVB (Red Green +Blue). Notez que le poids d'une image correspond à 3*nombre de pixels. + + +\chapter{Le tableur: fonctionnalités simples} +Un classeur permet de stocker des données numériques en vue de calculs +ou d'affichages graphiques (par opposition à l'affichage texte qu'on +vient de voir avec le format csv). Chaque classeur peut contenir de +nombreuses feuilles qu'on sélectionne avec des onglets. Chaque feuille +de calcul permet de saisir, contrôler, répertorier et analyser des +données (textuelles, numériques, fonctionnelles, etc.). Elle contient +des cellules éventuellement regroupées en plages. + +\section{Mise en forme} Chaque cellule peut être mise en forme avec +une palette complète d'outils. Il est possible de reproduire la mise +en forme à une autre cellule ou plage (voir le pinceau brosse). + +Dans un tableur, on peut insérer des graphiques dont on règle les +dimensions, les axes, les légendes et titres. En fonction du type de +données, on pourra privilégier le graphique en histogramme, en lignes +et courbes (pour représenter des tendances ou une évolution dans le +temps de valeurs numériques), à nuage, en secteurs (ou camemberts). + +\section{Fonctions de calcul} Voir la moyenne. + +\section{Tri, filtre et conversion de données} +\paragraph{Tri} Il est possible de trier des données en fonction de +textes (tri croissant ou décroissant), de nombres, de dates. Plusieurs +critères peuvent être définis (ex.: classement d'une classe par ordre +alphabétique des noms puis des notes obtenues). Pensez à cliquer sur +l'onglet Options pour déterminer les options de tri: vous pourrez +ainsi indiquer que la plage contient des étiquettes de colonne afin +d'éviter que les en-têtes de colonne soient triés avec les autres +données. + +\paragraph{Filtre} Le filtre automatique (Données>AutoFiltre) permet +de faciliter la recherche d'informations au sein d'une plage de +données. L'utilisateur peut ainsi choisir des informations qu'il +souhaite afficher ou masquer. + +\paragraph{Conversion} Une fonction permet de diviser une colonne de +données texte en plusieurs colonnes (Données>Texte en colonnes). Ex.: +à partir d'un nom complet, vous voulez une colonne nom et une colonne +prénom. + + +\section{Importation d'une source de données} +On peut vouloir importer une source de données dans un tableur, par +exemple une liste au format texte (qu'on peut visualiser dans un +traitement de textes en affichant les caractères non imprimables): +chaque caractère tabulation délimite le champ d'une cellule et chaque +pied de mouche indique qu'il faut passer à la ligne. Commençons par +ouvrir cette source de données (Fichier>Ouvrir): il faut alors +indiquer que le séparateur est la tabulation. + + +\chapter{Le tableur comme base de données} Un document Calc peut +constituer une base de données simplifiée. Dans une base de données, +un enregistrement est un groupe d'éléments de données liés entre eux +et traités comme une seule unité d'information. Chaque élément dans +l'enregistrement est appelé un champ. Une table est un ensemble +d'enregistrements. Chaque enregistrement, à l'intérieur d'une table, a +la même structure. Une table peut être vue comme une série de lignes +et de colonnes. On le voit, une feuille d'un document Calc a une +structure similaire à une table de base de données. + +Nous allons définir une plage de base de données de façon à trier, +grouper, rechercher et effectuer des calculs avec la plage comme si +c'était une base de données (Données>Définir la plage). + +\section{Utiliser des critères de recherche pour trouver des +données} +\paragraph{Exemple n°1} Comment compter toutes les cellules d'une +plage de données dont le contenu correspond à des critères de +recherche que nous aurons définis. Hypothèse de travail: nous +recherchons le nombre d'étudiants de la base dont la moyenne est égale +ou supérieure à 10 OU dont l'âge est inférieur ou égal à 17. Voici ce +qu'on doit saisir dans la cellule H5: +\begin{verbatim} =BDNB(A9:G51;0;A1:G3) +\end{verbatim} + +\paragraph{Commentaire} Le nom de la fonction est suivi d'une +parenthèse dans laquelle figurent: +\begin{itemize} +\item la plage de cellules contenant les données: A9:G51 +\item le champ de la base (colonne) utilisé pour les critères de +recherche: 0 +\item la plage de cellules contenant les critères de recherche: A1:G3 +\end{itemize} + +\paragraph{Exemple n°2} Comment déterminer le contenu de la cellule +d'une plage de données correspondant aux critères de +recherche. Hypothèse de travail: nous recherchons le nom de l'étudiant +qui a obtenu 5/20 au devoir n°1: +\begin{verbatim} =BDLIRE(A9:G51;"PRÉNOM";A1:C2) +\end{verbatim} + + +\section{Utiliser des formules pour trouver des données} Ne prenons +qu'un exemple: la fonction RECHERCHEV (pour recherche verticale): il +s'agit de récupérer des données issues d'une feuille différente de la +feuille de travail grâce à une "clé" commune aux deux feuilles. +\begin{enumerate} +\item dans la feuille n°1, j'ai les noms de tous mes étudiants et leur +n° d'étudiant; +\item dans la feuille n°2, j'ai les noms d'un seul groupe d'étudiants +et leur note. +\end{enumerate} --> Comment faire pour récupérer dans ma deuxième +feuille les n° d'étudiant du seul groupe concerné? +\begin{verbatim} =RECHERCHEV(A2;$Feuille1.$A$1:$B$120;2;0) +\end{verbatim} + +\paragraph{Commentaire} Notez que le premier argument est la valeur +cherchée dans la feuille 1: il s'agit, dans notre exemple, de chercher +l'étudiant Charles-Daniel (cellule A2). + +Le deuxième argument identifie les cellules où effectuer la recherche. + +Le troisième argument identifie la colonne à renvoyer: dans notre +exemple, celle des n° d'étudiants est la deuxième colonne de notre +feuille 1. + +Le dernier argument est facultatif. La valeur par défaut est 1 ou +VRAI, ce qui indique que la première colonne est triée dans l'ordre +croissant. Une valeur de 0 ou FAUX indique que les données ne sont pas +triées. + +Une fois que la recherche a abouti pour le premier étudiant, il faut +étendre la recherche à toutes les données de notre feuille 2: pour +cela, il suffit de faire un copier/coller en ayant pris la précaution +de protéger la formule en encadrant les numéros des colonnes du +chiffre \$. + + +\section{Utiliser des formules pour traiter des + données textuelles} +Plusieurs fonctions permettent de travailler sur du texte. En voici +quelques exemples: +\begin{itemize} +\item Mettre en majuscule la première lettre de chaque mot: +=NOMPROPRE(A1) +\item Supprimer les espaces en trop dans le texte de la cellule A1: +=SUPPRESPACE(A1) +\item Extraire le premier mot d'un texte saisi dans la cellule A1: +=GAUCHE(A1;CHERCHE(" ";A1;1)-1) +\end{itemize} + + + +\end{document} \ No newline at end of file diff --git a/fichiers/04-grep-bash.tex b/fichiers/04-grep-bash.tex new file mode 100644 index 0000000..48ea55f --- /dev/null +++ b/fichiers/04-grep-bash.tex @@ -0,0 +1,1226 @@ +\input{../_preamble} +\input{../_preamble_bbl} +\usepackage{menukeys} +\title{grep et bash} +\usepackage{float} +\usepackage{dingbat} +\usepackage[newfloat]{minted} +\SetupFloatingEnvironment{listing}{listname=Listings} +\setminted{ + bgcolor=Lavender, + breaklines, + breaksymbolright=\small\carriagereturn} +\setmintedinline{bgcolor=Lavender} +\usepackage{capt-of} +\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}} +} + +\NewDocumentCommand{\inputfile}{O{} m m O{application/x-sh}}{ + \marginpar{\attachandlink{scripts/#3}[#4]{Fichier + attaché}{\textcolor{blue}{Ouvrir le fichier}}} + \inputminted[#1]{#2}{scripts/#3} +} + +\begin{document} +\maketitle +\renewcommand{\contentsname}{Sommaire} +\tableofcontents + +\listoflistings + +\needspace{3\baselineskip} +\listoftables + +\chapter{grep, les expressions régulières} +\label{cha:grep-les-expressions}\commande{grep} +Les expressions régulières se rapprochent des \emph{wildcards} ou +\enquote{métacaractères} qui ont été présentés dans +\href{./01-ligne-de-commande.pdf#lnk_wildcards}{le cours sur la ligne + de commande}. C'est une technique commune à pour ainsi dire tous les +langages de programmation qui permet de construire des +\enquote{modèles}, en anglais \emph{patterns}, susceptibles de +capturer des chaînes de caractères. + +Par exemple, soit le fichier suivant: +\begin{minted}{text} +/usr/share/dict/cracklib-small +\end{minted} +Ce fichier fait partie d'un programme dont le rôle est de vérifier la +robustesse des mots de passe. Il contient un grand nombre d'entrées, à +raison d'un mot par ligne. Vérifions cela: +\begin{minted}{text} +[robert@kiddo courses]$ wc -l /usr/share/dict/cracklib-small +54763 /usr/share/dict/cracklib-small +\end{minted} +L'expression régulière suivante retourne tous les mots de cinq lettres +de ce fichier qui commencent par la lettre \verb|c| et se terminent +par la lettre \verb|h|: +\begin{minted}{text} +[robert@kiddo courses]$ grep '\' /usr/share/dict/cracklib-small +catch +cinch +clash +cloth +coach +conch +couch +cough +crash +crush +czech +\end{minted} + +\begin{quoting} + \textsc{Rem.} \verb|grep| recherche les modèles ligne par + ligne et retourne donc un résultat positif dès lors qu'un modèle + donné a été trouvé au moins une fois dans une ligne. +\end{quoting} + +\paragraph{Modèles} +Pour construire les modèles (\emph{patterns}), on peut utiliser les +symboles suivants\footnote{Cette liste n'est pas exhaustive.}: +\begin{xltabular}{\linewidth}{lX} + \toprule + Symbole & Signification \\ \midrule\endhead + \verb|.| & tout caractère unique\\ + \verb|?| & le caractère précédent est répété 0 ou une fois\\ + \verb|*| & le caractère précédent est répété 0 fois ou autant + de fois que possible\\ + \verb|+| & le caractère précédent est répété une fois \emph{au + moins}\\ + \verb|{n}| & le caractère précédent est répété exactement \emph{n} + fois\\ + \verb|{n,m}| & le caractère précédent est répété au moins \emph{n} + fois et au plus \emph{m} fois\\ + \verb|[abc]| & le caractère précédent est l'un de ceux qui se + trouvent entre les crochets droits\\ + \verb|[^abc]| & le caractère précédent n'est pas l'un de ceux qui se + trouvent entre les crochets droits\\ + \verb|[a-z]| & le caractère précédent est compris entre \emph{a} et + \emph{z}, dans l'ordre de la table des + caractères. C'est le sens du trait d'union entre les + lettres \verb|a| et \verb|z|. On peut bien sûr + combiner des chaînes avec et sans trait d'union. Par + exemple, \verb|[A-Ea-e]| correspond aux cinq + premières lettres de l'alphabet, en majuscule et en + minuscule. \\ + \verb|()| & ce qui est inclus entre les parenthèses est traité comme + un groupe \\ + + \verb+|+ & opérateur logique signifiant \emph{ou} \\ + \verb|^| & représente le début de la ligne\\ + \verb|$| & représente la fin de la ligne\\ \\ + \verb|\<| et \verb|\>| & représentent respectivement un début et une + fin de mot\\ + \bottomrule + \caption{grep \emph{patterns}} +\end{xltabular} + +\paragraph{grep, egrep} +\commande*{grep} +\commande{egrep}[|see{\texttt{grep}}] +À la place de \verb|grep|, on peut saisir à la ligne de commande +\verb|egrep| ou \verb|grep -E| pour \emph{extended regular + expressions}. Quelle est la différence? Retenez ici simplement que +sous \verb|grep| les metacaractères +\begin{minted}{text} +? + { } | ( ) +\end{minted} +doivent être précédés de la \emph{séquence d'échappement} \verb|\| +comme ceci: +\begin{minted}{text} +\? \+ \{ \} \| \( \) +\end{minted} +tandis que cela ne se fait pas avec \verb|egrep|. + +\paragraph{options} +La commande \verb|(e)grep| peut recevoir un grand nombre +d'options. Parmi ces options, retenons celles-ci: +\begin{description} +\item[-n] retourne les numéros des lignes dans lesquelles le modèle de + recherche a été trouvé. +\item[-c] retourne le nombre d'occurrences trouvées. +\item[-i] demande à \verb|grep| de ne pas faire de différence entre + les minuscules et les majuscules. +\item[-H] retourne le nom du fichier dans lequel le modèle recherché + est trouvé. +\item[-v] \emph{nie} le modèle recherché: \verb|grep| retournera donc + les lignes dans lesquelles le modèle \emph{n'a pas été trouvé}. +\end{description} + +\paragraph{Exemples} +Les exemples ci-dessous utilisent +\href{./01-ligne-de-commande.pdf#lnk_redirection}{la technique de la + redirection}. +\begin{minted}{text} +[robert@kiddo courses]$ cat /usr/share/dict/cracklib-small | grep '\' | grep 'ea' +scream +seagram +sealteam +seam +sidearm +steam +stream +sunbeam +sunbeam's +\end{minted} + \begin{quoting} + \textbf{Commentaire:} La ligne de commande fait ici successivement + les opérations suivantes: + \begin{enumerate} + \item Concaténation de toutes les lignes du fichier + \verb|cracklib-small| + \item Sélection de tous les mots qui commencent par la lettre + \verb|s| et se terminent par la lettre \verb|m|. + \item Parmi ces mots, sélection de ceux qui contiennent la chaîne + \verb|ea|. + \end{enumerate} + \end{quoting} +\begin{minted}{text} +[robert@kiddo courses]$ cat /usr/share/dict/cracklib-small | grep '\<.....\>' | grep -E 'o{2}|e{2}' | grep 't' | column -c 70 +afoot fleet needn't skeet steep taboo three tweed +beets foote roost sleet steer taboo's three's +boost greet roots sooth stood teems tools +booth hoots scoot steed stool teens tooth +boots loots sheet steel stoop teeth trees +booty meets shoot steen sweet tepee troop +\end{minted} +\begin{quoting} + \textbf{Commentaire:} La ligne de commande fait ici successivement + les opérations suivantes: + \begin{enumerate} + \item Concaténation de toutes les lignes du fichier + \verb|cracklib-small| + \item Sélection des mots de cinq caractères. + \item Parmi ces mots, sélection de ceux qui contiennent \emph{soit} + la chaîne \verb|oo| \emph{soit} la chaîne \verb|ee|. + \item Enfin, sélection, parmi ces derniers mots, de ceux qui + contiennent la lettre \verb|t| + \item La dernière ligne, dont on n'a pas étudié la syntaxe, demande + l'affichage du résultat sous la forme de colonnes tabulées. + \end{enumerate} +\end{quoting} + +\chapter{bash} +\label{cha:bash} +Comme on l'a vu, \verb|bash| est le \emph{shell} le plus répandu sur +les systèmes Linux aujourd'hui. On peut écrire en \verb|bash| des +\emph{scripts}, autrement dit de petits programmes informatiques, pour +réaliser des suites d'opérations plus ou moins complexes. + +Voici un exemple très simple. Prenons les lignes suivantes: +\begin{minted}[linenos]{text} +mkdir sauvegarde +cp *.tex sauvegarde +zip -r sauvegarde.zip sauvegarde +\end{minted} +Ces trois lignes exécutent successivement les opérations suivantes: +\begin{enumerate} +\item Création d'un répertoire intitulé \verb|sauvegarde| +\item Copie de tous les fichiers \TeX{} dans le répertoire + \verb|sauvegarde| +\item Création d'une archive \verb|.zip| de tout le répertoire. +\end{enumerate} + +Pour éviter de répéter ces trois lignes de commande et d'encourir le +risque de se tromper dans la saisie, on peut décider de les écrire +dans un fichier texte que l'on appellera par exemple \verb|backup.sh| +de la façon suivante: +\begin{minted}[linenos]{bash} +#!/bin/bash +mkdir sauvegarde +cp *.tex sauvegarde +zip -r sauvegarde.zip sauvegarde +\end{minted} + +Il suffit alors de demander à \verb|bash| d'exécuter ce fichier pour +que les trois opérations soient réalisées d'un coup. Comme les scripts +écrits en \verb|bash| sont interprétés par le \textsl{shell} +\verb|bash|, \emph{toute ligne de commande peut être exécutée dans un + script}. Réciproquement, \emph{tout ce qui peut entrer dans un + script peut aussi être exécuté à la ligne de commande}. + +\section{L'éditeur de texte} +\label{sec:lediteur-de-texte} +C'est dans un \emph{éditeur de texte} que l'on saisit tout code +informatique. Certains éditeurs de texte sont très simples à +utiliser. Nous allons prendre ici l'exemple de l'un des plus simples, +\verb|nano|. Pour le lancer, il suffit de saisir à la ligne de +commande: \mintinline{text}|nano|. Après avoir lancé \verb|nano| et +saisi le script donné ci-dessus, voici ce que l'on obtient: +\begin{minted}[linenos,fontsize=\footnotesize]{text} + GNU nano 2.8.2 Nouvel espace + +#!/bin/bash +mkdir sauvegarde +cp *.tex sauvegarde +zip -r sauvegarde.zip sauvegarde + + + + + + + + + + + + + + + + + +^G Aide ^O Écrire ^W Chercher ^K Couper ^J Justifier ^C Pos. cur. +^X Quitter ^R Lire fich.^\ Remplacer ^U Coller ^T Orthograp.^_ Aller lig. +\end{minted} + +Les lignes 24 et 25 correspondent au menu de \verb|nano|. On n'y +accède pas par la souris, mais à l'aide des \emph{raccourcis clavier} +qui sont tous préfixés par le \emph{caret} (\verb|^|) qui représente +la touche \keys{Ctrl} du clavier. Donc pour quitter le programme, on +appuiera sur \keys{Ctrl-X}: voici ce que montre \verb|nano| au bas du +terminal après avoir saisi \keys{Ctrl-X}: +\begin{minted}[linenos,fontsize=\footnotesize]{text} +Écrire l'espace modifié ? (Répondre « Non » ABANDONNE les modifications.) + O Oui + N Non ^C Annuler +\end{minted} +Les opérations suivantes sont donc possibles: +\begin{enumerate} +\item \keys{O}: sauvegarde le fichier. +\item \keys{N}: quitte \verb|nano| sans sauvegarder. +\item \keys{Ctrl-C}: annule l'opération et retourne à l'éditeur de texte. +\end{enumerate} +Appuyons sur la touche \keys{O}. \verb|nano| nous invite alors à +entrer le nom du script: +\begin{minted}[linenos,fontsize=\footnotesize]{text} +Nom du fichier à écrire: backup.sh +^G Aide M-D Format DOS M-A Ajout (à la fin)M-B Copie de sécu. +^C Annuler M-M Format Mac M-P Ajout (au début)^T Parcourir +\end{minted} +Après avoir entré le nom du fichier et appuyé sur la touche +\keys{Enter} pour confirmer le choix, on retourne au terminal et à la +ligne de commande. + +\section{Le \emph{shebang}} +\label{sec:le-shebang} +La première ligne du script \verb|backup.sh| donné en exemple +ci-dessus appelle un commentaire particulier: +\begin{minted}[linenos]{bash} +#!/bin/bash +\end{minted} + +Dans cette ligne, la séquence \mintinline{bash}|#!| s'appelle le +\emph{shebang}. Par convention, le \emph{shebang} est un préfixe que +l'on fait suivre du nom du programme qui doit interpréter le script, +précédé de son chemin d'accès absolu. + +Le \emph{shebang} est important car il permet d'accéder aux +interpréteurs auxquels on souhaite accéder depuis la ligne de +commande. Par exemple, pour un script écrit en Python2, la première +ligne sera: +\begin{minted}[linenos]{python} +#!/usr/bin/env python2 +""" + Mon premier script en Python +""" +print("bonjour le monde!") +\end{minted} + +\section{Les commentaires} +\label{sec:les-commentaires} +En \verb|bash|, tout ce qui, sur une même ligne, suit le signe +\mintinline{bash}|#| \emph{n'est ni interprété, ni exécuté}. On +utilise donc ce signe pour introduire des \emph{commentaires} dans le +code informatique. + +Les commentaires ne servent pas uniquement à introduire des remarques +pour son usage personnel. Ils servent aussi, et surtout, à donner des +indications sur le code lui-même pour permettre aux autres de mieux +comprendre la programmation. Si le code est bien commenté, alors on +doit pouvoir le lire comme on lit un livre. Cela est très important +car les programmes longs et complexes dépassent souvent et parfois +même survivent à leur auteur. + +Si le code est bien compris, il sera facilement mis à jour, corrigé et +augmenté par d'autres programmeurs. + +L'art de commenter le code informatique tout en l'écrivant porte le +nom de \emph{literate programming}. Il a été inventé par Donald +E.~Knuth, le créateur de \TeX, qui a posé tous les principes de cet +art dans le cadre de la programmation en +\textsf{WEB}\footnote{\cite{Knuth1983}. Voir également en ligne + \url{http://www.literateprogramming.com/}}. + +Pour un exemple de code commenté, voir le \vref{lst:copyten}. + +\section{Exécution} +\label{sec:execution} +Il faut ici approfondir la notion de \emph{permissions} sur les +fichiers qui a été présentée dans le cours sur la +\href{./01-ligne-de-commande.pdf#lnk_permissions}{ligne + de commande}. Nous avons en effet étudié trois types de permissions +sur les fichiers: en lecture, en écriture et en exécution. Revenons +sur les permissions données par défaut au script \verb|backup.sh|: +\begin{minted}{text} +[robert@kiddo courses]$ ls -l backup.sh +-rw-r--r-- 1 robert robert 82 17 sept. 22:06 backup.sh +\end{minted} +Soit: +\begin{itemize} +\item lecture et écriture pour l'utilisateur \verb|robert| (\verb|rw|); +\item lecture seule pour le groupe \verb|robert| (\verb|r|); +\item lecture seule pour le reste du monde (\verb|r|) +\end{itemize} + +\paragraph{chmod} +\commande*{chmod} +La commande qui permet de changer les droits s'appelle +\verb|chmod|. Pour comprendre comment l'utiliser, il faut savoir que +les permissions sont traduites par des valeurs numériques, à savoir: +\begin{itemize} +\item 4 pour le droit \emph{lecture}; +\item 2 pour le droit \emph{écriture}; +\item 1 pour le droit \emph{exécution}. +\end{itemize} +Ces valeurs peuvent être additionnées. On analyse donc ainsi les +permissions sur le fichier \verb|backup.sh|: +\begin{itemize} +\item utilisateur \verb|robert|, lecture + écriture: $4+2=6$; +\item groupe \verb|robert|, lecture: $4$; +\item reste du monde, lecture: $4$. +\end{itemize} +Soit $644$. Pour ajouter à l'utilisateur \verb|robert| seulement la +permission en exécution, il faudrait donc porter cette valeur à +$744$. Nous allons ici donner ce droit à la fois à \verb|robert|, au +groupe \verb|robert| et au reste du monde, soit une valeur de +$755$. La syntaxe est la suivante: +\begin{minted}{text} +chmod xyz +\end{minted} +où \verb|xyz| sont les trois chiffres qui représentent les permissions. +\begin{minted}[escapeinside=||, linenos]{text} +[robert@kiddo courses]$ chmod 755 backup.sh +[robert@kiddo courses]$ ls -l --color backup.sh +-rwxr-xr-x 1 robert robert 82 17 sept. 22:06 |\textcolor{green}{backup.sh}| +\end{minted} +\begin{quoting} + \textbf{Commentaire}: + \begin{enumerate} + \item La commande \verb|chmod| a été entrée à la ligne 1. + \item À la ligne 2, nous avons lancé la commande + \commande{ls}\mintinline{text}|ls -l --color| sur le fichier + \verb|backup.sh|: les droits listés à la ligne 3 montrent bien que + la valeur \verb|x| a été ajoutée aux trois endroits possibles. On + voit enfin que l'option \verb|--color| affiche en vert les + fichiers qui sont exécutables. + \end{enumerate} +\end{quoting} + +Nous pouvons désormais exécuter notre script: +\begin{minted}[linenos,escapeinside=||]{text} +[robert@kiddo courses]$ ls -l --color +total 36 +-rwxr-xr-x 1 robert robert 82 17 sept. 22:06 |\textcolor{green}{backup.sh}| +-rw-r--r-- 1 robert robert 165 16 sept. 19:40 bibliography.bib +drwxr-xr-x 5 robert robert 4096 17 sept. 22:30 |\textcolor{blue}{fichiers}| +-rw-r--r-- 1 robert robert 680 16 sept. 18:34 makefile +-rw-r--r-- 1 robert robert 898 16 sept. 19:39 _preamble_bbl.tex +-rw-r--r-- 1 robert robert 699 14 sept. 15:02 _preamble-ed.tex +-rw-r--r-- 1 robert robert 719 16 sept. 19:39 _preamble.tex +-rw-r--r-- 1 robert robert 1407 17 sept. 00:15 README.md +-rw-r--r-- 1 robert robert 1804 17 sept. 00:15 README.tex +[robert@kiddo courses]$ ./backup.sh + adding: sauvegarde/ (stored 0%) + adding: sauvegarde/README.tex (deflated 57%) + adding: sauvegarde/_preamble.tex (deflated 45%) + adding: sauvegarde/_preamble_bbl.tex (deflated 57%) + adding: sauvegarde/_preamble-ed.tex (deflated 44%) +[robert@kiddo courses]$ ls -l --color +total 44 +-rwxr-xr-x 1 robert robert 82 17 sept. 22:06 |\textcolor{green}{backup.sh}| +-rw-r--r-- 1 robert robert 165 16 sept. 19:40 bibliography.bib +drwxr-xr-x 5 robert robert 4096 17 sept. 22:31 |\textcolor{blue}{fichiers}| +-rw-r--r-- 1 robert robert 680 16 sept. 18:34 makefile +-rw-r--r-- 1 robert robert 898 16 sept. 19:39 _preamble_bbl.tex +-rw-r--r-- 1 robert robert 699 14 sept. 15:02 _preamble-ed.tex +-rw-r--r-- 1 robert robert 719 16 sept. 19:39 _preamble.tex +-rw-r--r-- 1 robert robert 1407 17 sept. 00:15 README.md +-rw-r--r-- 1 robert robert 1804 17 sept. 00:15 README.tex +drwxr-xr-x 2 robert robert 4096 17 sept. 22:31 |\textcolor{blue}{sauvegarde}| +-rw-r--r-- 1 robert robert 2828 17 sept. 22:31 sauvegarde.zip +[robert@kiddo courses]$ ls sauvegarde +_preamble_bbl.tex _preamble-ed.tex _preamble.tex README.tex +\end{minted} +\begin{quoting} + \textbf{Commentaire:} + \begin{itemize} + \item lignes 1--11: la commande \commande{ls}\verb|ls -l --color| + donne l'état du dossier \emph{avant} l'exécution du script + \verb|backup.sh|; + \item lignes 12--17: exécution du script et messages du terminal; + \item lignes 18--30: la commande \verb|ls -l --color| donne l'état du + dossier \emph{après} l'exécution du script \verb|backup.sh|. On + voit qu'un nouveau répertoire \verb|sauvegarde| a été créé, de + même qu'un fichier archive \verb|sauvegarde.zip|; + \item lignes 31--32: la commande \verb|ls sauvegarde| liste le + contenu de ce répertoire. On y trouve tous les fichiers + \verb|.tex| qui y ont été copiés par le script. + \end{itemize} +\end{quoting} + +\paragraph{PATH} Un dernier point reste à éclaircir: à la ligne 12, +pourquoi a-t-on écrit \mintinline{bash}|./backup.sh| et non pas +simplement \mintinline{bash}|backup.sh|? Tout simplement pour des +raisons de sécurité. En effet, le principe est que les fichiers +exécutables se trouvent dans certains répertoires-système spécialement +conçus pour les accueillir. C'est pour cette raison que l'on peut +lancer les commandes \verb|bash| sans avoir à les préfixer. Or notre +répertoire de travail ne fait partie de ces répertoires spéciaux. Il +faut donc préfixer tout script exécutable qui s'y trouve par son +\emph{chemin d'accès}, soit relatif, soit absolu. On a choisi ici la +première méthode: dans la séquence \mintinline{text}|./|, le point +représente le répertoire courant tandis que le \emph{slash} précise +qu'il s'agit d'un chemin d'accès. Sans le \emph{slash}, le +\emph{shell} aurait compris le point comme un préfixe de fichier +caché. + +\section{Les variables} +\label{sec:les-variables} +Les variables sont des informations temporaires qui peuvent être +stockées et rappelées à tout moment. L'exemple qui suit va donner +l'occasion d'étudier une nouvelle commande, +\commande{echo}\verb|echo|, dont le rôle est justement de retourner +au terminal la chaîne de caractères qu'on lui passe en argument: +\begin{minted}[linenos]{text} +[robert@kiddo courses]$ mysystem="Linux" +[robert@kiddo courses]$ echo 'Mon système est $mysystem.' +Mon système est $mysystem. +[robert@kiddo courses]$ echo "Mon système est $mysystem." +Mon système est Linux. +\end{minted} + +\begin{quoting} + \textbf{Commentaire:} + \begin{description} + \item[Définition] Pour \emph{définir une variable}, on lui donne un + nom, suivi du signe $=$, suivi de sa définition entre guillemets + droits. + \item[Rappel] Pour \emph{rappeler} la valeur d'une variable, on + saisit le nom qu'on lui a donné, préfixé par le signe \verb|$|. + \end{description} + \begin{mdframed}[backgroundcolor=Cyan] + Observez la différence dans l'usage des guillemets! + \href{./01-ligne-de-commande.pdf#lnk_guillemets}{Comme + on le sait}, les guillemets servent à indiquer au \emph{shell} + que les espaces ne sont pas des caractères actifs. Il y a + cependant une grande différence entre les guillemets simples et + les guillemets doubles: les premiers renvoient une expression + littérale dans laquelle rien n'est interprété (lignes~2--3) tandis + que les seconds permettent l'interprétation des variables + (lignes~4--5). + \end{mdframed} +\end{quoting} + +Certaines variables sont automatiquement définies par \emph{bash}. Par +exemple: +\begin{enumerate} +\item \verb|$0|: renvoie le nom du script en cours d'exécution. +\item \verb|$1 - $9|: désignent les arguments successifs passés au + script. +\end{enumerate} + +Nous pouvons désormais perfectionner le script \verb|backup.sh|: +\begin{minted}[linenos]{bash} +#!/bin/bash +echo "Veuillez choisir l'extension des fichiers à sauvegarder" +echo "(sans le point):" +read -p 'extension: ' ext +echo "Veuillez choisir le nom du dossier de sauvegarde:" +read -p 'dossier: ' backupdir +mkdir "$backupdir" +cp *.$ext "$backupdir" +zip -r "$backupdir".zip "$backupdir" +echo "Terminé. $0 a copié vos fichiers .$ext dans $backupdir" +echo "et l'archive $backupdir.zip a été créée." +\end{minted} + +\paragraph{read} +\label{ref:read} +\commande*{read} Cette nouvelle commande est expliquée dans +le commentaire qui suit\footnote{Voir aussi plus loin + \vpageref{ref:read-plus}.}: +\begin{quoting} + \textbf{Commentaire:} + \begin{enumerate} + \item Une nouvelle commande a été introduite ici: aux lignes~4 et 6, + \verb|read| attend que l'utilisateur saisisse quelque chose au + clavier. Ensuite, la valeur saisie au clavier est associée à une + variable qui peut être reprise dans le script. On a également + passé à \verb|read| l'option \verb|-p| qui permet d'ajouter un + \emph{prompt} spécifique. + \item Aux lignes 7, 8 et 9, on a pris la précaution de mettre entre + guillemets doubles le rappel de la variable: + \verb|"$backupdir"|. On sait en effet que beaucoup d'utilisateurs + utilisent les espaces dans les noms des fichiers. Ici, la variable + étant rappelée à l'intérieur de guillemets doubles, elle sera + toujours interprétée correctement par \emph{bash}. + \end{enumerate} +\end{quoting} + +Exécution du script \verb|./backup.sh tex|: +\begin{minted}[linenos]{text} +[robert@kiddo courses]$ ./backup.sh +Veuillez choisir l'extension des fichiers à sauvegarder +(sans le point): +extension: tex +Veuillez choisir le nom du dossier de sauvegarde: +dossier: Houba + adding: Houba/ (stored 0%) + adding: Houba/README.tex (deflated 57%) + adding: Houba/_preamble.tex (deflated 45%) + adding: Houba/_preamble_bbl.tex (deflated 57%) + adding: Houba/_preamble-ed.tex (deflated 44%) +Terminé. ./backup.sh a copié vos fichiers .tex dans Houba +et l'archive Houba.zip a été créée. +\end{minted} +\begin{quoting} + \textbf{Commentaire:} + \begin{enumerate} + \item Les valeurs attendues ont été saisies par l'utilisateur aux + lignes~4 et 6. + \item À la ligne~12, le script a utilisé la variable \verb|$0| pour + retourner son propre nom. + \end{enumerate} +\end{quoting} + +\section{Captures et substitutions} +\label{sec:capt-et-subst} +Cette technique simple permet de transformer en variable le résultat +d'une commande. Il suffit de placer la commande entre parenthèses +précédées du signe $=$. Exemple: +\begin{minted}[linenos]{text} +[robert@kiddo courses]$ nbre=$(ls | wc -l) +[robert@kiddo courses]$ echo $nbre +8 +\end{minted} + +\needspace{2\baselineskip} +\begin{quoting} + \textbf{Commentaire:} + \begin{enumerate} + \item À la ligne~1, la commande \commande{ls}\verb|ls| liste les + fichiers, puis son résultat est interprété par + \commande{wc}\verb|wc -l| qui compte le nombre de fichiers + retournés. + \item La variable \verb|$nbre| contient donc ce dernier résultat. + \end{enumerate} +\end{quoting} + +Utilisons cette technique pour perfectionner notre script +\verb|backup.sh| (voir ci-dessous la ligne~9): +\begin{minted}[linenos]{bash} +#!/bin/bash +echo "Veuillez choisir l'extension des fichiers à sauvegarder" +echo "(sans le point):" +read -p 'extension: ' ext +echo "Veuillez choisir le nom du dossier de sauvegarde:" +read -p 'dossier: ' backupdir +mkdir "$backupdir" +cp *.$ext "$backupdir" +nbre=$(ls $backupdir/*.$ext | wc -l) +zip -r "$backupdir".zip "$backupdir" +echo "Terminé. $0 a copié $nbre fichiers .$ext dans $backupdir" +echo "et l'archive $backupdir.zip a été créée." +\end{minted} + +Exécution: +\begin{minted}[linenos]{text} +[robert@kiddo courses]$ ./backup.sh +Veuillez choisir l'extension des fichiers à sauvegarder +(sans le point): +extension: tex +Veuillez choisir le nom du dossier de sauvegarde: +dossier: Houba + adding: Houba/ (stored 0%) + adding: Houba/README.tex (deflated 57%) + adding: Houba/_preamble.tex (deflated 45%) + adding: Houba/_preamble_bbl.tex (deflated 57%) + adding: Houba/_preamble-ed.tex (deflated 44%) +Terminé. ./backup.sh a copié 4 fichiers .tex dans Houba +et l'archive Houba.zip a été créée. +\end{minted} + +\section{Conditions} +\label{sec:conditions} +Il est souvent très utile de n'exécuter des lignes de code que si +certaines conditions sont remplies. Reprenons ici l'exemple du script +\verb|backup.sh|: au moment où le script crée le répertoire de +sauvegarde, il ne contrôle pas si ce répertoire existe déjà, ce qui est +un défaut. Voici comment on peut créer une condition adaptée à cette +situation: +\begin{minted}[linenos]{bash} +if [ -d "$backupdir" ] +then + echo "Le dossier $backupdir existe déjà. Veuillez relancer le" + echo "programme et saisir un autre nom." + exit 1 +else + mkdir "$backupdir" +fi +\end{minted} +\begin{quoting} + \textbf{Commentaire:} + \begin{enumerate} + \item Observez la structure de la condition: + \begin{itemize} + \item ligne 1: \commande*{if}\mintinline{bash}|if| + $\rightarrow$ \emph{si } où la condition est posée + entre crochets. Dans l'expression entre les crochets, % + \verb|-d "$backupdir"|, \verb|-d| signifie: \verb|$backupdir| + existe \emph{et} est un répertoire; + \item ligne 2: \commande*{then}\mintinline{bash}|then| + $\rightarrow$ \emph{alors, passez à la ligne suivante}; + \item ligne 6: \commande*{else}\mintinline{bash}|else| + $\rightarrow$ \emph{autrement, passez à la ligne suivante}; + \item ligne 8: \commande*{fi}\mintinline{bash}|fi| + $\rightarrow$ \emph{fin de la condition} (en fait les deux + lettres de la conjonction \verb|if| écrite à l'envers). + \end{itemize} + \item À la ligne 5, la commande \commande{exit}\verb|exit 1| + ordonne au programme de se terminer immédiatement et de renvoyer + la valeur \verb|1| comme numéro d'état (\emph{status number}). Par + convention, \verb|0| est pour \emph{true} (le programme a bien été + exécuté) et \verb|1| est pour \emph{false} (il y a eu une erreur). + \end{enumerate} +\end{quoting} + +Voici donc comment se présente le script \verb|backup.sh| une fois la +condition insérée: +\captionof{listing}{bash: exemple de condition \texttt{if-then-else}% +\label{lst:if-then-else}} +\inputfile[linenos,highlightlines={7-14}]{bash}{backup.sh} + +\subsection{Conditions en série} +\label{sec:conditions-en-serie} +Supposons que le répertoire de sauvegarde ait été supprimé mais que +l'archive \verb|.zip| correspondante ne l'ait pas été. Dans ce cas, le +script \verb|backup.sh| l'écraserait. Pour éviter cela, nous pouvons +utiliser dans le script l'instruction +\commande*{elif}\verb|elif| qui permet de construire des +conditions en série. Littéralement, \verb|elif| est pour \emph{else + if}, \enquote{ou autrement, si\ldots}. Voici donc ce qu'il faut +ajouter: +\begin{minted}{bash} +elif [ -e "$backupdir".zip ] + then + echo "L'archive $backupdir.zip existe déjà. Veuillez la supprimer" + echo "ou la déplacer en dehors de ce dossier, puis relancez le" + echo "programme." + exit 1 +\end{minted} + +Ce qui donne le script \verb|backup-mk2.sh| suivant: +\captionof{listing}{bash: instruction \texttt{elif}\label{lst:elif}} +\inputfile[linenos,highlightlines={12-17}]{bash}{backup-mk2.sh} + +\subsection{Tests} +\label{sec:tests} +Le tableau suivant donne la liste des tests les plus répandus que l'on +peut associer aux conditions. Les tests sont placés entre crochets +droits comme le montre la ligne~7 du \vref{lst:if-then-else}. +\begin{xltabular}{.77\linewidth}{lX} + \toprule + Opérateur & Description \\ + \midrule\endhead + \verb|! expr| & \verb|expr| est faux \\ + \verb|-n str| & la longueur de \verb|str| $>0$\footnote{Comprendre: + \texttt{str} existe.} \\ + \verb|-z str| & la longueur de \verb|str| $=0$\footnote{Comprendre: + \texttt{str} n'existe pas.}\\ + \verb|str1 = str2| & \verb|str1| est égal à \verb|str2|\\ + \verb|str1 != str2| & \verb|str1| n'est pas égal à \verb|str2|\\ + \verb|int1 -eq int2| & les nombres \verb|int1| et \verb|int2| sont + égaux\\ + \verb|int1 -gt int2| & \verb|int1| $>$ \verb|int2|\\ + \verb|int1 -lt int2| & \verb|int1| $<$ \verb|int2|\\ + \verb|-d fichier| & \verb|fichier| existe et est un répertoire\\ + \verb|-e fichier| & \verb|fichier| existe \\ + \verb|-s fichier| & \verb|fichier| existe et n'est pas vide (taille + $>0$) \\ + \verb|-r fichier| & \verb|fichier| existe et est accessible en + lecture\\ + \verb|-w fichier| & \verb|fichier| existe et est accessible en + écriture \\ + \verb|-x fichier| & \verb|fichier| existe et est accessible en + exécution \\ + \bottomrule + \caption{tests\label{tab:tests}} + \label{tab:tests} +\end{xltabular} + +\paragraph{test} +\commande*{test} À l'intérieur du script \verb|bash|, les +crochets renvoient en fait à une commande par ailleurs disponible: +\verb|test|. La commande \verb|test| renvoie en fait la sortie +\verb|0| si le résultat est \emph{vrai} et \verb|1| si le résultat est +\emph{faux}. Le terminal ne retourne pas le resultat, mais celui-ci +est associé à une variable +\verb|$?| que l'on peut afficher par la commande: +\commande{echo}\mintinline{bash}|echo $?|. En voici quelques +exemples: +\begin{minted}[linenos]{text} +[robert@kiddo courses]$ ls +bibliography.bib makefile _preamble-ed.tex _preamble.tex README.tex +fichiers _preamble_bbl.tex _preamble.log README.md +[robert@kiddo courses]$ test -d fichiers +[robert@kiddo courses]$ echo $? +0 +[robert@kiddo courses]$ test -x makefile +[robert@kiddo courses]$ echo $? +1 +[robert@kiddo courses]$ test -e makefile +[robert@kiddo courses]$ echo $? +0 +[robert@kiddo courses]$ test 0123 = 123 +[robert@kiddo courses]$ echo $? +1 +[robert@kiddo courses]$ test 0123 -eq 123 +[robert@kiddo courses]$ echo $? +0 +\end{minted} +\begin{quoting} + \textbf{Commentaire ---} Cet exemple montre quelle est la différence + entre le test $=$ pour qui il faut une stricte équivalence dans les + chaînes de caractères, et le test \verb|-eq| qui est un test + arithmétique. +\end{quoting} + +\subsection{Indentation} +\label{sec:indentation} +L'indentation est une technique qui consiste à donner aux lignes de +code différentes profondeurs de marge à gauche de façon à distinguer +clairement des blocs logiques. Les lignes 7--20 du +\vref{lst:if-then-else} en donnent un exemple. L'indentation permet de +faire apparaître clairement ce qui dépend de l'instruction +\commande{if}\verb|if| (l.~7), puis \commande{elif}\verb|elif| +(l.~12) et enfin \commande{else}\verb|else| (l.~18). + +Cette technique est commune à tous les langages informatiques et tous +les programmeurs l'utilisent. En Python, que nous étudierons plus +tard, l'indendation fait même partie du langage lui-même, puisque +Python a recours à l'indentation pour structurer les blocs logiques, à +la différence d'autres langages qui ont recours soit à des +déclarations explicites telles que \verb|begin ... end| ou encore à +des opérateurs tels que \verb|{ ... }| + +Voici un exemple d'indentation d'une structure dans laquelle on a +placé une condition à l'intérieur d'une autre condition: +\captionof{listing}{bash: exemple d'indentation} +\inputfile[linenos]{bash}{greaterthan.sh} + +\subsection{Opérateurs booléens} +\label{sec:operateurs-booleens} +Les opérateurs booléens, dont le nom est tiré du mathématicien anglais +George Boole, sont des opérateurs logiques que l'on peut associer à +des conditions. En voici deux ici: +\begin{enumerate} +\item \verb+||+ pour \emph{ou}; +\item \verb|&&| pour \emph{et}. +\end{enumerate} + +Par exemple, dans le \vref{lst:elif} ci-dessus, on pourrait remplacer +les lignes 7--20 par le code ci-dessous: +\begin{minted}[linenos]{bash} +if [ -d "$backupdir" ] || [ -e "$backupdir".zip ] + then + echo "Le dossier $backupdir et/ou l'archive $backupdir.zip" + echo "existent déjà. Veuillez relancer le programme et saisir" + echo "un autre nom." + exit 1 +else + mkdir "$backupdir" +fi +\end{minted} + +\subsection{case} +\label{sec:case}\commande*{case} +\verb|case| est une instruction qui permet d'exécuter différentes +actions en fonction de la valeur d'une variable. Elle est intéressante +à étudier ici car elle fait appel à la fois à la notion de variable et +aux expressions régulières. La syntaxe est la suivante: +\begin{minted}[linenos]{bash} +case $var in + expr1) + + ;; + expr2) + + ;; +esac +\end{minted} +\begin{quoting} + \textbf{Commentaire:} + \begin{enumerate} + \item L'instruction \verb|case| se termine par \verb|esac|, de même, + comme on l'a vu, que l'expression \verb|if| se termine par + \verb|fi|. + \item Les expressions régulières sont suivies d'une parenthèse + fermante. + \item Pour passer d'un jeu de commande au jeu suivant, on écrit, sur + une ligne \verb|;;| + \end{enumerate} +\end{quoting} + +Le \vref{lst:case} montre un exemple facile à comprendre de cette +technique. +\captionof{listing}{bash: instruction \texttt{case}\label{lst:case}} +\inputfile[linenos]{bash}{animal.sh} +\begin{quoting} + \textbf{Commentaire:} + \begin{enumerate} + \item À la ligne 4, l'utilisateur est invité à entrer une + réponse. L'instruction \commande{read}\verb|read| associe la + réponse à la variable \verb|animal|. + \item À la ligne 6, l'instruction \verb|case| reprend la variable + qui est donc préfixée par le signe \verb|$|. + \item Aux lignes 7 et 10, on permet à l'utilisateur d'entrer soit le + mot \emph{chien}, soit le mot \emph{chat}. L'initiale peut être + une minuscule ou une majuscule. + \item À la ligne 13, comme le signe \verb|*| est en \emph{bash} le + \emph{wildcard} qui représente toute séquence de caractères, la + commande de la ligne~14 sera forcément exécutée si les tests des + lignes~7 et~10 ont échoué. + \end{enumerate} +\end{quoting} + +\begin{quoting} + \textbf{Remarque:} à la place de l'instruction \verb|case|, on + recommande aujourd'hui d'utiliser une nouvelle instruction, + \commande{switch}\verb|switch|, dont la syntaxe, plus complexe, + n'est pas étudiée ici. +\end{quoting} + +\section{Boucles} +\label{sec:boucles} +Les boucles (en anglais: \emph{loops}) servent à indiquer qu'une série +d'instructions doit reprendre et continuer à s'exécuter aussi +longtemps qu'une condition donnée est remplie ou n'est pas remplie. + +Prenons un exemple simple. Nous avons dans un répertoire plusieurs +centaines d'images de différents formats et nous souhaitons convertir +au format \verb|.png| toutes les images qui sont enregistrées au +format \verb|.tiff|. + +Pour convertir une seule image, nous pouvons utiliser l'outil en ligne +de commande \verb|convert| fourni par le programme +\emph{imagemagick}\footnote{\url{http://www.imagemagick.org}}. Pour +convertir une seule image, la syntaxe est la suivante: +\begin{minted}{bash} +convert image.tiff image.png +\end{minted} + +Mais comment faire pour en convertir un grand nombre pris dans un +répertoire qui en compte des centaines enregistrées dans des formats +différents? + +\paragraph{basename} +\commande*{basename}Avant de continuer, il faut dire un mot de la +commande \verb|basename| que nous allons utiliser ici. Cette commande +permet de dépouiller un nom de fichier de son chemin d'accès et de son +extension. La syntaxe est la suivante: +\begin{minted}[escapeinside=||]{text} +basename -s .|\emph{ext}| |\emph{file}| +\end{minted} +où \emph{ext} est le nom de l'extension et \emph{file} le nom du +fichier. Voici un exemple: +\begin{minted}{text} +[robert@kiddo fichiers]$ ls -l images/ +total 252 +-rw-r--r-- 1 robert robert 96404 2 juil. 18:32 02-ascii.png +-rw-r--r-- 1 robert robert 33951 20 juin 19:59 02-donnees1.png +-rw-r--r-- 1 robert robert 11503 20 juin 20:01 02-donnees2.png +-rw-r--r-- 1 robert robert 17450 3 juil. 17:43 02-exercice_formats.png +-rw-r--r-- 1 robert robert 87510 14 sept. 15:06 02-unicode.png +[robert@kiddo fichiers]$ basename -s .png images/* +02-ascii +02-donnees1 +02-donnees2 +02-exercice_formats +02-unicode +\end{minted} + +\paragraph{for-do-done} +\commande*{for}\commande*{do}\commande*{done} +La boucle que nous allons utiliser fait appel à trois instructions: +\begin{enumerate} +\item \verb|for| prend comme argument un nom qui sera ensuite traité + comme une variable. Le nom de la variable est suivi de l'instruction + \commande{in}\verb|in| et d'un nom de fichier qui contient des + données séparées par des espaces ou bien d'une expression dans + laquelle on a placé des + \href{./01-ligne-de-commande.pdf#lnk_wildcards}{\emph{wildcards}}. +\item \verb|do| est suivi des commandes qu'il faut exécuter sur chaque + élément retourné par l'instruction \verb|for| \ldots{} \verb|in|. +\item \verb|done| marque la fin de la boucle. +\end{enumerate} + +Voici maintenant le script qui assure la conversion du format +\verb|.tiff| vers le format \verb|.png|: +\captionof{listing}{bash: \texttt{for ... do ... done}} +\inputfile[linenos]{bash}{tiff2png.sh} + +\begin{quoting} + \textbf{Commentaire:} + \begin{enumerate} + \item Comprendre ainsi le début de la ligne~2 % + (\mintinline{bash}|for file in|): \enquote{pour tout \texttt{file} + dans\ldots} où \verb|file| définit une variable dont la valeur + pourra ensuite être rappelée par \verb|$file|. Le reste de la + ligne est une \emph{double capture} (v.~\emph{supra}, + \vref{sec:capt-et-subst}): + \begin{enumerate} + \item \verb|$(ls *.tiff)| liste et retourne tous les fichiers dont + l'extension est \verb|.tiff| + \item \verb|$(basename -s .tiff $(ls *.tiff))| demande à + \verb|basename| de dépouiller tous ces fichiers de leur + extension \verb|.tiff| et retourne la liste des noms seuls. + \end{enumerate} + \item La variable \verb|file| est donc une liste constituée des noms + de tous les fichiers \verb|.tiff| sans leur extension. La ligne~3 + les convertit tous les uns après les autres vers le format + \verb|.png|. + \end{enumerate} +\end{quoting} + +\paragraph{while} +\commande*{while} L'expression \verb|while| exécute les +lignes de code qui suivent aussi longtemps qu'un test donné retourne +un résultat positif (\enquote{vrai}, en anglais \emph{true}). Le +script \verb|countlines.sh|, donné dans le \cref{lst:countlines} +ci-dessous, utilise cette expression pour compter les lignes des +fichiers\footnote{Pour une autre façon plus simple d'écrire le même + programme, voir le \vref{lst:countlines-mk2}.}. +\captionof{listing}{bash: \texttt{while}\label{lst:countlines}} +\inputfile[linenos,highlightlines={13,16-17}]{bash}{countlines.sh} + +\paragraph{read} +\label{ref:read-plus}\commande*{read} +On a déjà présenté plus haut \vpageref{ref:read} cette +instruction. Pour bien comprendre le \cref{lst:countlines}, il faut +savoir que la fonction de \verb|read| est de \emph{lire une ligne}, +quelle que soit cette ligne, depuis l'entrée standard du \emph{shell} +(en anglais: \emph{standard input}). Dans le \vref{lst:case}, la ligne +en question était donc constituée d'une saisie au clavier dans +laquelle la ligne était formée par une chaîne de caractères terminée +par un \emph{retour charriot} (\emph{carriage return}). + +\begin{mdframed}[backgroundcolor=Cyan] + \verb|read| admet aussi une option \verb|-r| qui est importante: + quand cette option est activée, le caractère \verb|\| + (\emph{backslash}) est traité comme un caractère ordinaire, et non + comme un caractère actif. Pour simplement compter les lignes d'un + fichier, il faut ajouter cette option car en \emph{bash} le + \emph{backslash} est précisément un caractère actif: à la fin d'une + ligne, il sert à joindre cette ligne à la ligne suivante. +\end{mdframed} + +Étudions de près les lignes~13--17 du \cref{lst:countlines}: +l'instruction \verb|while| (l.~13) se termine à la ligne~17 par +\verb|done|. Et aussitôt à ce moment, +\href{./01-ligne-de-commande.pdf#lnk_redirection}{l'opérateur + de redirection} \mintinline{bash}|<| lit le contenu du fichier dont +le nom correspond à la variable \verb|file| et le passe en argument à +la boucle \verb|while ... done|. + +\paragraph{Commentaire du \cref{lst:countlines}} +\begin{enumerate} +\item À la ligne~6, on crée une variable \verb|numline| à laquelle + on attribue la valeur \verb|0|. Elle servira donc de compteur. +\item L'instruction essentielle est à la ligne~13: + \mintinline{bash}|while read -r line|: comme ce qui suit + \verb|while| \emph{est un test}, ce test donnera un résultat positif + aussi longtemps que la variable \verb|line| existe, c'est-à-dire + aussi longtemps que l'opérateur de redirection \mintinline{bash}|<| + de la ligne~17 envoie des lignes terminées par un retour + charriot. Tant que cette condition est remplie, la commande de la + ligne~16 sera exécutée, et le compteur de lignes sera incrémenté + d'une unité à chaque fois. +\item Les instructions des lignes~20--25 sont faciles à + suivre. Étudiez-les à l'aide du \vref{tab:tests}: vous pourrez + comprendre comment la programmation peut être adaptée pour suivre + les règles de l'orthographe française. +\end{enumerate} + +Exécutons maintenant le script: +\begin{minted}{text} +[robert@kiddo courses]$ ./countlines.sh +Entrez le nom du fichier dont vous voulez compter les lignes: +Fichier: whack +Erreur: le fichier whack n'existe pas. +[robert@kiddo courses]$ ./countlines.sh +Entrez le nom du fichier dont vous voulez compter les lignes: +Fichier: makefile +Votre fichier makefile compte 21 lignes. +\end{minted} + +\paragraph{until} +\commande*{until}À la différence de \verb|while|, +\verb|until| exécute les instructions qui suivent jusqu'au moment où +le résultat du test associé à \verb|until| devient \emph{positif} +(\emph{true}). Pour prendre un exemple très simple, le script suivant, +que l'on appellera \verb|rah.sh|, demande combien de fois on souhaite +tirer la queue d'un lion: +\captionof{listing}{bash: comment faire rugir le lion?} +\inputfile[linenos]{bash}{rah.sh} + +\begin{quoting} + \textbf{Commentaire:} + \begin{enumerate} + \item La condition posée à la ligne~17 se comprend ainsi: + \enquote{faites ce qui suit jusqu'à ce que le compteur de + rugissements atteigne une valeur supérieure à celle définie par + l'utilisateur. Si la valeur est supérieure, sortez de la boucle.} +\item À la ligne~20, on demande à \emph{bash} d'attendre une seconde. +\item À la ligne~21, on incrémente de 1 la valeur du compteur de + rugissements (voir ci-dessus le \vref{lst:countlines}, l.~14), puis + on reprend la boucle à la ligne~17. + \end{enumerate} +\end{quoting} + +Exécution du script \verb|rah.sh|: +\begin{minted}{text} +[robert@kiddo courses]$ ./rah.sh +Combien de fois tirez-vous la queue du lion? 3 +Raaaaaaaaahhhhhhhhhhhh! (1) +Raaaaaaaaahhhhhhhhhhhh! (2) +Raaaaaaaaahhhhhhhhhhhh! (3) +[robert@kiddo courses]$ +\end{minted} + +\paragraph{break} +\commande*{break} \verb|break| est une instruction qui +ordonne de quitter immédiatement la boucle dans laquelle on se +trouve. Supposons par exemple que l'on écrive un programme dans lequel +on souhaite limiter une action telle que la copie de +fichiers. L'instruction \verb|break| sera exécutée dès que la limite +est atteinte. Appelons ce script \verb|copyten.sh|: +\captionof{listing}{bash: copie d'un nombre limité de + fichiers\label{lst:copyten}} +\inputfile[linenos]{bash}{copyten.sh} + +Ce script donne un exemple de code commenté. Comme on le voit, les +commentaires peuvent se trouver sur des lignes isolées aussi bien que +sur des lignes qui contiennent des commandes\footnote{Voir ci-dessus, + \vref{sec:les-commentaires}.}. + +Exécution du script \verb|copyten.sh|: +\begin{minted}{text} +[robert@kiddo courses]$ ls *.txt +01.txt 03.txt 05.txt 07.txt 09.txt 11.txt +02.txt 04.txt 06.txt 08.txt 10.txt 12.txt +[robert@kiddo courses]$ ./copyten.sh +Attention: ce programme copie au maximum 10 fichiers. +Que souhaitez-vous copier: *.txt +Répertoire de destination: Houba +Erreur: la destination doit être un répertoire. + Le cas échéant, utilisez "mkdir Houba" + pour créer le répertoire de destination. +[robert@kiddo courses]$ mkdir Houba +[robert@kiddo courses]$ ./copyten.sh +Attention: ce programme copie au maximum 10 fichiers. +Que souhaitez-vous copier: *.txt +Répertoire de destination: Houba +Terminé. 10 fichiers au maximum ont été copiés dans Houba. +[robert@kiddo courses]$ ls Houba/ +01.txt 02.txt 03.txt 04.txt 05.txt 06.txt 07.txt +08.txt 09.txt 10.txt +\end{minted} + +\paragraph{continue} +\commande*{continue} À l'inverse de \verb|break|, +\verb|continue| demande à \emph{bash} d'interrompre l'itération +courante mais sans quitter la boucle, puis de reprendre la boucle à +partir de l'itération suivante. C'est une façon de prévoir des +exceptions. Par exemple, nous pouvons modifier le script +\ref{lst:copyten} comme suit: + +\captionof{listing}{bash: copie d'un nombre limité de + fichiers sans échec si le fichier source n'existe pas} +\inputfile[linenos,highlightlines={26-31}]{bash}{copyten-mk2.sh} + +\begin{quoting} + \textbf{Commentaire:} + \begin{enumerate} + \item À la ligne~30, l'instruction \verb|continue| intervient dans + le cas où le fichier à copier n'existe pas (voir le test de la + ligne~26). + \item Dans ce cas, le fichier est créé par la ligne~28. + \item Puis \verb|continue| interrompt la boucle et la reprend depuis + la ligne~24. + \end{enumerate} +\end{quoting} + +Voici ce que donne l'exécution de ce script: +\begin{minted}{text} +[robert@kiddo courses]$ ./copyten-mk2.sh +Attention: ce programme copie au maximum 10 fichiers. +Que souhaitez-vous copier: tchic.txt +Répertoire de destination: Houba +création de tchic.txt qui n'existe pas... +Terminé. 10 fichiers au maximum ont été copiés dans Houba. +[robert@kiddo courses]$ ls Houba/ +tchic.txt +\end{minted} + +\section{Les fonctions} +\label{sec:les-fonctions} +Comme leur nom l'indique, les fonctions permettent d'exécuter des +instructions de façon autonome dans un script. Elles peuvent être +ensuite utilisées aussi souvent que nécessaire et permettent donc de +réduire la taille du script. Deux formats sont permis: +\begin{minted}[linenos]{bash} +# Format 1 +ma_fonction () { + +} + +# Format 2 +function ma_fonction { + +} +\end{minted} + +Ces deux formats sont strictement équivalents. Le premier est le plus +répandu car il rappelle ce qui se fait dans de nombreux autres +langages où l'on utilise les parenthèses pour passer aux fonctions des +variables, des chaînes de caractères, des paramètres optionnels ou +même d'autres fonctions. Toutefois, en \emph{bash}, on ne met jamais +rien entre les parenthèses qui sont purement décoratives. + +Le script suivant permet de parvenir au même résultat que le script +qui a été présenté dans le \vref{lst:countlines}: +\captionof{listing}{bash: exemple de + fonction\label{lst:countlines-mk2}} +\inputfile[linenos]{bash}{countlines-mk2.sh} + +Pour terminer, exécutons cette nouvelle version de notre script +ici appelée \verb|countlines-mk2.sh|: + +\begin{minted}{text} +[robert@kiddo courses]$ ./countlines-mk2.sh +Entrez le nom du fichier dont vous voulez compter les lignes: +Fichier: makefile +Votre fichier makefile compte 21 lignes. +\end{minted} + +\printindex[cmds] +\end{document} diff --git a/fichiers/images/02-ascii.png b/fichiers/images/02-ascii.png deleted file mode 100644 index 8a5c75a..0000000 Binary files a/fichiers/images/02-ascii.png and /dev/null differ diff --git a/fichiers/images/02-donnees1.png b/fichiers/images/02-donnees1.png deleted file mode 100644 index 369e48d..0000000 Binary files a/fichiers/images/02-donnees1.png and /dev/null differ diff --git a/fichiers/images/02-donnees2.png b/fichiers/images/02-donnees2.png deleted file mode 100644 index 3aeb112..0000000 Binary files a/fichiers/images/02-donnees2.png and /dev/null differ diff --git a/fichiers/images/02-exercice_formats.png b/fichiers/images/02-exercice_formats.png deleted file mode 100644 index 382fb85..0000000 Binary files a/fichiers/images/02-exercice_formats.png and /dev/null differ diff --git a/fichiers/images/02-unicode.png b/fichiers/images/02-unicode.png deleted file mode 100644 index a8856e9..0000000 Binary files a/fichiers/images/02-unicode.png and /dev/null differ diff --git a/fichiers/images/03-ascii.png b/fichiers/images/03-ascii.png new file mode 100644 index 0000000..8a5c75a Binary files /dev/null and b/fichiers/images/03-ascii.png differ diff --git a/fichiers/images/03-donnees1.png b/fichiers/images/03-donnees1.png new file mode 100644 index 0000000..369e48d Binary files /dev/null and b/fichiers/images/03-donnees1.png differ diff --git a/fichiers/images/03-donnees2.png b/fichiers/images/03-donnees2.png new file mode 100644 index 0000000..3aeb112 Binary files /dev/null and b/fichiers/images/03-donnees2.png differ diff --git a/fichiers/images/03-exercice_formats.png b/fichiers/images/03-exercice_formats.png new file mode 100644 index 0000000..382fb85 Binary files /dev/null and b/fichiers/images/03-exercice_formats.png differ diff --git a/fichiers/images/03-unicode.png b/fichiers/images/03-unicode.png new file mode 100644 index 0000000..a8856e9 Binary files /dev/null and b/fichiers/images/03-unicode.png differ -- cgit v1.2.3