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/03-grep-bash.tex | 1226 --------------------------------------------- 1 file changed, 1226 deletions(-) delete mode 100644 fichiers/03-grep-bash.tex (limited to 'fichiers/03-grep-bash.tex') 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} -- cgit v1.2.3