diff options
author | Robert Alessi <alessi@robertalessi.net> | 2018-09-24 21:34:02 +0200 |
---|---|---|
committer | Robert Alessi <alessi@robertalessi.net> | 2018-09-24 21:34:02 +0200 |
commit | 41deb6ed180587999908e6a459ad21e55bab1f57 (patch) | |
tree | 7d6c71233ac85b288ed0f676c47f92b2d0930387 | |
parent | bfb57e9cc5e9fb66c402687818890d042babbf58 (diff) | |
download | courses-41deb6ed180587999908e6a459ad21e55bab1f57.tar.gz |
done writing 03-grep-bash.tex
-rw-r--r-- | _preamble.tex | 2 | ||||
-rw-r--r-- | fichiers/01-ligne-de-commande.tex | 3 | ||||
-rw-r--r-- | fichiers/03-grep-bash.tex | 335 |
3 files changed, 305 insertions, 35 deletions
diff --git a/_preamble.tex b/_preamble.tex index d71b26d..ba992e0 100644 --- a/_preamble.tex +++ b/_preamble.tex | |||
@@ -24,8 +24,10 @@ | |||
24 | \usepackage{cleveref} | 24 | \usepackage{cleveref} |
25 | \crefname{table}{tableau}{tableaux} | 25 | \crefname{table}{tableau}{tableaux} |
26 | 26 | ||
27 | \usepackage{kalendarium} | ||
27 | \usepackage[type={CC}, modifier={by-sa}, version ={3.0}]{doclicense} | 28 | \usepackage[type={CC}, modifier={by-sa}, version ={3.0}]{doclicense} |
28 | \author{Robert Alessi} | 29 | \author{Robert Alessi} |
30 | \date{\KalToday} | ||
29 | \lowertitleback{\footnotesize\textcopyright{} 2018 Robert Alessi | 31 | \lowertitleback{\footnotesize\textcopyright{} 2018 Robert Alessi |
30 | \mailto[courses]{robert.alessi@cnrs.fr} | 32 | \mailto[courses]{robert.alessi@cnrs.fr} |
31 | \doclicenseThis} | 33 | \doclicenseThis} |
diff --git a/fichiers/01-ligne-de-commande.tex b/fichiers/01-ligne-de-commande.tex index b4d438f..aaf7db2 100644 --- a/fichiers/01-ligne-de-commande.tex +++ b/fichiers/01-ligne-de-commande.tex | |||
@@ -8,11 +8,12 @@ | |||
8 | \usepackage{dingbat} | 8 | \usepackage{dingbat} |
9 | \usepackage{mdframed} | 9 | \usepackage{mdframed} |
10 | \mdfsetup{ | 10 | \mdfsetup{ |
11 | everyline, | ||
11 | backgroundcolor=Lavender, | 12 | backgroundcolor=Lavender, |
12 | hidealllines=true} | 13 | hidealllines=true} |
13 | \usepackage{minted} | 14 | \usepackage{minted} |
14 | \surroundwithmdframed{minted} | ||
15 | \setminted{ | 15 | \setminted{ |
16 | bgcolor=Lavender, | ||
16 | breaklines, | 17 | breaklines, |
17 | breaksymbolright=\small\carriagereturn} | 18 | breaksymbolright=\small\carriagereturn} |
18 | \setmintedinline{bgcolor=Lavender} | 19 | \setmintedinline{bgcolor=Lavender} |
diff --git a/fichiers/03-grep-bash.tex b/fichiers/03-grep-bash.tex index aaf007f..9b3c54a 100644 --- a/fichiers/03-grep-bash.tex +++ b/fichiers/03-grep-bash.tex | |||
@@ -6,16 +6,17 @@ | |||
6 | \usepackage{units} | 6 | \usepackage{units} |
7 | \usepackage{booktabs} | 7 | \usepackage{booktabs} |
8 | \usepackage{xltabular} | 8 | \usepackage{xltabular} |
9 | \usepackage{dingbat} | ||
10 | \usepackage{mdframed} | 9 | \usepackage{mdframed} |
11 | \mdfsetup{ | 10 | \mdfsetup{ |
11 | everyline, | ||
12 | backgroundcolor=Lavender, | 12 | backgroundcolor=Lavender, |
13 | hidealllines=true} | 13 | hidealllines=true} |
14 | \usepackage{float} | 14 | \usepackage{float} |
15 | \usepackage{dingbat} | ||
15 | \usepackage[newfloat]{minted} | 16 | \usepackage[newfloat]{minted} |
16 | \SetupFloatingEnvironment{listing}{listname=Listings} | 17 | \SetupFloatingEnvironment{listing}{listname=Listings} |
17 | \surroundwithmdframed{minted} | ||
18 | \setminted{ | 18 | \setminted{ |
19 | bgcolor=Lavender, | ||
19 | breaklines, | 20 | breaklines, |
20 | breaksymbolright=\small\carriagereturn} | 21 | breaksymbolright=\small\carriagereturn} |
21 | \setmintedinline{bgcolor=Lavender} | 22 | \setmintedinline{bgcolor=Lavender} |
@@ -28,7 +29,10 @@ | |||
28 | \maketitle | 29 | \maketitle |
29 | \renewcommand{\contentsname}{Sommaire} | 30 | \renewcommand{\contentsname}{Sommaire} |
30 | \tableofcontents | 31 | \tableofcontents |
32 | |||
31 | \listoflistings | 33 | \listoflistings |
34 | |||
35 | \needspace{3\baselineskip} | ||
32 | \listoftables | 36 | \listoftables |
33 | 37 | ||
34 | \chapter{grep, les expressions régulières} | 38 | \chapter{grep, les expressions régulières} |
@@ -352,6 +356,8 @@ art dans le cadre de la programmation en | |||
352 | \textsf{WEB}\footnote{\cite{Knuth1983}. Voir également en ligne | 356 | \textsf{WEB}\footnote{\cite{Knuth1983}. Voir également en ligne |
353 | \url{http://www.literateprogramming.com/}}. | 357 | \url{http://www.literateprogramming.com/}}. |
354 | 358 | ||
359 | Pour un exemple de code commenté, voir le \vref{lst:copyten}. | ||
360 | |||
355 | \section{Exécution} | 361 | \section{Exécution} |
356 | \label{sec:execution} | 362 | \label{sec:execution} |
357 | Il faut ici approfondir la notion de \emph{permissions} sur les | 363 | Il faut ici approfondir la notion de \emph{permissions} sur les |
@@ -695,7 +701,6 @@ fi | |||
695 | 701 | ||
696 | Voici donc comment se présente le script \verb|backup.sh| une fois la | 702 | Voici donc comment se présente le script \verb|backup.sh| une fois la |
697 | condition insérée: | 703 | condition insérée: |
698 | \begin{listing}[H] | ||
699 | \begin{minted}[linenos,highlightlines={7-14}]{bash} | 704 | \begin{minted}[linenos,highlightlines={7-14}]{bash} |
700 | #!/bin/bash | 705 | #!/bin/bash |
701 | echo "Veuillez choisir l'extension des fichiers à sauvegarder" | 706 | echo "Veuillez choisir l'extension des fichiers à sauvegarder" |
@@ -717,9 +722,8 @@ zip -r "$backupdir".zip "$backupdir" | |||
717 | echo "Terminé. $0 a copié $nbre fichiers .$ext dans $backupdir" | 722 | echo "Terminé. $0 a copié $nbre fichiers .$ext dans $backupdir" |
718 | echo "et l'archive $backupdir.zip a été créée." | 723 | echo "et l'archive $backupdir.zip a été créée." |
719 | \end{minted} | 724 | \end{minted} |
720 | \caption{bash: exemple de condition \texttt{if-then-else}} | 725 | \captionof{listing}{bash: exemple de condition \texttt{if-then-else}% |
721 | \label{lst:if-then-else} | 726 | \label{lst:if-then-else}} |
722 | \end{listing} | ||
723 | 727 | ||
724 | \subsection{Conditions en série} | 728 | \subsection{Conditions en série} |
725 | \label{sec:conditions-en-serie} | 729 | \label{sec:conditions-en-serie} |
@@ -741,7 +745,6 @@ elif [ -e "$backupdir".zip ] | |||
741 | \end{minted} | 745 | \end{minted} |
742 | 746 | ||
743 | Ce qui donne le script \verb|backup.sh| suivant: | 747 | Ce qui donne le script \verb|backup.sh| suivant: |
744 | \begin{listing}[H] | ||
745 | \begin{minted}[linenos,highlightlines={12-17}]{bash} | 748 | \begin{minted}[linenos,highlightlines={12-17}]{bash} |
746 | #!/bin/bash | 749 | #!/bin/bash |
747 | echo "Veuillez choisir l'extension des fichiers à sauvegarder" | 750 | echo "Veuillez choisir l'extension des fichiers à sauvegarder" |
@@ -769,9 +772,7 @@ zip -r "$backupdir".zip "$backupdir" | |||
769 | echo "Terminé. $0 a copié $nbre fichiers .$ext dans $backupdir" | 772 | echo "Terminé. $0 a copié $nbre fichiers .$ext dans $backupdir" |
770 | echo "et l'archive $backupdir.zip a été créée." | 773 | echo "et l'archive $backupdir.zip a été créée." |
771 | \end{minted} | 774 | \end{minted} |
772 | \caption{bash: instruction \texttt{elif}} | 775 | \captionof{listing}{bash: instruction \texttt{elif}\label{lst:elif}} |
773 | \label{lst:elif} | ||
774 | \end{listing} | ||
775 | 776 | ||
776 | \subsection{Tests} | 777 | \subsection{Tests} |
777 | \label{sec:tests} | 778 | \label{sec:tests} |
@@ -865,7 +866,6 @@ des opérateurs tels que \verb|{ ... }| | |||
865 | 866 | ||
866 | Voici un exemple d'indentation d'une structure dans laquelle on a | 867 | Voici un exemple d'indentation d'une structure dans laquelle on a |
867 | placé une condition à l'intérieur d'une autre condition: | 868 | placé une condition à l'intérieur d'une autre condition: |
868 | \begin{listing}[H] | ||
869 | \begin{minted}[linenos]{bash} | 869 | \begin{minted}[linenos]{bash} |
870 | #!/bin/bash | 870 | #!/bin/bash |
871 | if [ $1 -gt 10 ] | 871 | if [ $1 -gt 10 ] |
@@ -879,8 +879,7 @@ else | |||
879 | echo "Il faut aller au-dessus de 10 pour avoir une réponse!" | 879 | echo "Il faut aller au-dessus de 10 pour avoir une réponse!" |
880 | fi | 880 | fi |
881 | \end{minted} | 881 | \end{minted} |
882 | \caption{bash: exemple d'indentation} | 882 | \captionof{listing}{bash: exemple d'indentation} |
883 | \end{listing} | ||
884 | 883 | ||
885 | \subsection{Opérateurs booléens} | 884 | \subsection{Opérateurs booléens} |
886 | \label{sec:operateurs-booleens} | 885 | \label{sec:operateurs-booleens} |
@@ -937,7 +936,6 @@ esac | |||
937 | 936 | ||
938 | Le \vref{lst:case} montre un exemple facile à comprendre de cette | 937 | Le \vref{lst:case} montre un exemple facile à comprendre de cette |
939 | technique. | 938 | technique. |
940 | \begin{listing}[H] | ||
941 | \begin{minted}[linenos]{bash} | 939 | \begin{minted}[linenos]{bash} |
942 | #!/bin/bash | 940 | #!/bin/bash |
943 | 941 | ||
@@ -956,9 +954,7 @@ case $animal in | |||
956 | ;; | 954 | ;; |
957 | esac | 955 | esac |
958 | \end{minted} | 956 | \end{minted} |
959 | \caption{bash: instruction \texttt{case}} | 957 | \captionof{listing}{bash: instruction \texttt{case}\label{lst:case}} |
960 | \label{lst:case} | ||
961 | \end{listing} | ||
962 | \begin{quoting} | 958 | \begin{quoting} |
963 | \textbf{Commentaire:} | 959 | \textbf{Commentaire:} |
964 | \begin{enumerate} | 960 | \begin{enumerate} |
@@ -1048,15 +1044,13 @@ La boucle que nous allons utiliser fait appel à trois instructions: | |||
1048 | 1044 | ||
1049 | Voici maintenant le script qui assure la conversion du format | 1045 | Voici maintenant le script qui assure la conversion du format |
1050 | \verb|.tiff| vers le format \verb|.png|: | 1046 | \verb|.tiff| vers le format \verb|.png|: |
1051 | \begin{listing}[H] | ||
1052 | \begin{minted}[linenos]{bash} | 1047 | \begin{minted}[linenos]{bash} |
1053 | #!/bin/bash | 1048 | #!/bin/bash |
1054 | for file in $(basename -s .tiff $(ls *.tiff)) | 1049 | for file in $(basename -s .tiff $(ls *.tiff)) |
1055 | do convert "$file".tiff "$file".png | 1050 | do convert "$file".tiff "$file".png |
1056 | done | 1051 | done |
1057 | \end{minted} | 1052 | \end{minted} |
1058 | \caption{bash: \texttt{for ... do ... done}} | 1053 | \captionof{listing}{bash: \texttt{for ... do ... done}} |
1059 | \end{listing} | ||
1060 | 1054 | ||
1061 | \begin{quoting} | 1055 | \begin{quoting} |
1062 | \textbf{Commentaire:} | 1056 | \textbf{Commentaire:} |
@@ -1087,7 +1081,8 @@ lignes de code qui suivent aussi longtemps qu'un test donné retourne | |||
1087 | un résultat positif (\enquote{vrai}, en anglais \emph{true}). Le | 1081 | un résultat positif (\enquote{vrai}, en anglais \emph{true}). Le |
1088 | script \verb|countlines.sh|, donné dans le \cref{lst:countlines} | 1082 | script \verb|countlines.sh|, donné dans le \cref{lst:countlines} |
1089 | ci-dessous, utilise cette expression pour compter les lignes des | 1083 | ci-dessous, utilise cette expression pour compter les lignes des |
1090 | fichiers. | 1084 | fichiers\footnote{Une autre façon plus simple d'écrire le même |
1085 | programme, voir le \vref{lst:countlines-mk2}.}. | ||
1091 | \begin{minted}[linenos,highlightlines={13,16-17}]{bash} | 1086 | \begin{minted}[linenos,highlightlines={13,16-17}]{bash} |
1092 | #!/bin/bash | 1087 | #!/bin/bash |
1093 | 1088 | ||
@@ -1101,7 +1096,7 @@ if [ ! -e $file ] || [ -z $file ] | |||
1101 | echo "Erreur: le fichier $file n'existe pas." | 1096 | echo "Erreur: le fichier $file n'existe pas." |
1102 | exit 1 | 1097 | exit 1 |
1103 | else | 1098 | else |
1104 | while read line | 1099 | while read -r line |
1105 | # 'let' permet de poser des opérations arithmétiques; | 1100 | # 'let' permet de poser des opérations arithmétiques; |
1106 | # à la place, on aurait pu écrire: do ((++numline)) | 1101 | # à la place, on aurait pu écrire: do ((++numline)) |
1107 | do let "numline = numline + 1" | 1102 | do let "numline = numline + 1" |
@@ -1128,6 +1123,16 @@ en question était donc constituée d'une saisie au clavier dans | |||
1128 | laquelle la ligne était formée par une chaîne de caractères terminée | 1123 | laquelle la ligne était formée par une chaîne de caractères terminée |
1129 | par un \emph{retour charriot} (\emph{carriage return}). | 1124 | par un \emph{retour charriot} (\emph{carriage return}). |
1130 | 1125 | ||
1126 | \begin{mdframed}[backgroundcolor=Cyan] | ||
1127 | \verb|read| admet aussi une option \verb|-r| qui est importante: | ||
1128 | quand cette option est activée, le caractère \verb|\| | ||
1129 | (\emph{backslash}) est traité comme un caractère ordinaire, et non | ||
1130 | comme un caractère actif. Pour simplement compter les lignes d'un | ||
1131 | fichier, il faut ajouter cette option car en \emph{bash} le | ||
1132 | \emph{backslash} est précisément un caractère actif: à la fin d'une | ||
1133 | ligne, il sert à joindre cette ligne à la ligne suivante. | ||
1134 | \end{mdframed} | ||
1135 | |||
1131 | Étudions de près les lignes~13--17 du \cref{lst:countlines}: | 1136 | Étudions de près les lignes~13--17 du \cref{lst:countlines}: |
1132 | l'instruction \verb|while| (l.~13) se termine à la ligne~17 par | 1137 | l'instruction \verb|while| (l.~13) se termine à la ligne~17 par |
1133 | \verb|done|. Et aussitôt à ce moment, | 1138 | \verb|done|. Et aussitôt à ce moment, |
@@ -1141,14 +1146,14 @@ la boucle \verb|while ... done|. | |||
1141 | \item À la ligne~6, on crée une variable \verb|numline| à laquelle | 1146 | \item À la ligne~6, on crée une variable \verb|numline| à laquelle |
1142 | on attribue la valeur \verb|0|. Elle servira donc de compteur. | 1147 | on attribue la valeur \verb|0|. Elle servira donc de compteur. |
1143 | \item L'instruction essentielle est à la ligne~13: | 1148 | \item L'instruction essentielle est à la ligne~13: |
1144 | \mintinline{bash}|while read line|: comme ce qui suit \verb|while| | 1149 | \mintinline{bash}|while read -r line|: comme ce qui suit |
1145 | \emph{est un test}, ce test donnera un résultat positif aussi | 1150 | \verb|while| \emph{est un test}, ce test donnera un résultat positif |
1146 | longtemps que la variable \verb|line| existe, c'est-à-dire aussi | 1151 | aussi longtemps que la variable \verb|line| existe, c'est-à-dire |
1147 | longtemps que l'opérateur de redirection \mintinline{bash}|<| de la | 1152 | aussi longtemps que l'opérateur de redirection \mintinline{bash}|<| |
1148 | ligne~17 envoie des lignes terminées par un retour charriot. Tant | 1153 | de la ligne~17 envoie des lignes terminées par un retour |
1149 | que cette condition est remplie, la commande de la ligne~16 sera | 1154 | charriot. Tant que cette condition est remplie, la commande de la |
1150 | exécutée, et le compteur de lignes sera incrémenté d'une unité à | 1155 | ligne~16 sera exécutée, et le compteur de lignes sera incrémenté |
1151 | chaque fois. | 1156 | d'une unité à chaque fois. |
1152 | \item Les instructions des lignes~20--25 sont faciles à | 1157 | \item Les instructions des lignes~20--25 sont faciles à |
1153 | suivre. Étudiez-les à l'aide du \vref{tab:tests}: vous pourrez | 1158 | suivre. Étudiez-les à l'aide du \vref{tab:tests}: vous pourrez |
1154 | comprendre comment la programmation peut être adaptée pour suivre | 1159 | comprendre comment la programmation peut être adaptée pour suivre |
@@ -1164,14 +1169,276 @@ Erreur: le fichier whack n'existe pas. | |||
1164 | [robert@kiddo courses]$ ./countlines.sh | 1169 | [robert@kiddo courses]$ ./countlines.sh |
1165 | Entrez le nom du fichier dont vous voulez compter les lignes: | 1170 | Entrez le nom du fichier dont vous voulez compter les lignes: |
1166 | Fichier: makefile | 1171 | Fichier: makefile |
1167 | Votre fichier makefile compte 17 lignes. | 1172 | Votre fichier makefile compte 21 lignes. |
1173 | \end{minted} | ||
1174 | |||
1175 | \paragraph{until} | ||
1176 | \index[cmds]{until|textbf}À la différence de \verb|while|, | ||
1177 | \verb|until| exécute les instructions qui suivent jusqu'au moment où | ||
1178 | le résultat du test associé à \verb|until| devient \emph{positif} | ||
1179 | (\emph{true}). Pour prendre un exemple très simple, le script suivant, | ||
1180 | que l'on appellera \verb|roar.sh|, demande combien de fois on souhaite | ||
1181 | tirer la queue d'un lion: | ||
1182 | \begin{minted}[linenos]{bash} | ||
1183 | #!/bin/bash | ||
1184 | |||
1185 | read -p 'Combien de fois tirez-vous la queue du lion? ' rahtimes | ||
1186 | |||
1187 | # Définition du compteurs de rugissements: | ||
1188 | rah=1 | ||
1189 | |||
1190 | until [ $rah -gt $rahtimes ] | ||
1191 | do | ||
1192 | echo "Raaaaaaaaahhhhhhhhhhhh! ($rah)" | ||
1193 | sleep 1 | ||
1194 | ((++rah)) | ||
1195 | done | ||
1196 | \end{minted} | ||
1197 | \captionof{listing}{bash: comment faire rugir le lion?} | ||
1198 | |||
1199 | \begin{quoting} | ||
1200 | \textbf{Commentaire:} | ||
1201 | \begin{enumerate} | ||
1202 | \item La condition posée à la ligne~8 se comprend ainsi: | ||
1203 | \enquote{faites ce qui suit jusqu'à ce que le compteurs de | ||
1204 | rugissements atteingne une valeur supérieure à celle définie par | ||
1205 | l'utilisateur. Si la valeur est supérieure, sortez de la boucle.} | ||
1206 | \item À la ligne~11, on demande à \emph{bash} d'attendre une seconde. | ||
1207 | \item À la ligne~12, on incrémente de 1 la valeur du compteur de | ||
1208 | rugissements (voir ci-dessus le \vref{lst:countlines}, l.~15), puis | ||
1209 | on reprend la boucle à la ligne~8. | ||
1210 | \end{enumerate} | ||
1211 | \end{quoting} | ||
1212 | |||
1213 | Exécution du script \verb|roar.sh|: | ||
1214 | \begin{minted}{text} | ||
1215 | [robert@kiddo courses]$ ./roar.sh | ||
1216 | Combien de fois tirez-vous la queue du lion? 3 | ||
1217 | Raaaaaaaaahhhhhhhhhhhh! (1) | ||
1218 | Raaaaaaaaahhhhhhhhhhhh! (2) | ||
1219 | Raaaaaaaaahhhhhhhhhhhh! (3) | ||
1220 | [robert@kiddo courses]$ | ||
1221 | \end{minted} | ||
1222 | |||
1223 | \paragraph{break} | ||
1224 | \index[cmds]{break|textbf} \verb|break| est une instruction qui | ||
1225 | ordonne de quitter immédiatement la boucle dans laquelle on se | ||
1226 | trouve. Supposons par exemple que l'on écrive un programme dans lequel | ||
1227 | on souhaite limiter une action telle que la copie de | ||
1228 | fichiers. L'instruction \verb|break| sera exécutée dès que la limite | ||
1229 | est atteinte. Appelons ce script \verb|copyten.sh|: | ||
1230 | \begin{minted}[linenos]{bash} | ||
1231 | #!/bin/bash | ||
1232 | |||
1233 | # création du compteur de fichiers copiés. | ||
1234 | countfiles=0 | ||
1235 | |||
1236 | # On demande quels fichiers doivent être copiés. Mais avant cela, on | ||
1237 | # explique à l'utilisateur ce que fait ce programme. | ||
1238 | echo "Attention: ce programme copie au maximum 10 fichiers." | ||
1239 | read -p 'Que souhaitez-vous copier: ' files | ||
1240 | |||
1241 | # On demande la destination: | ||
1242 | read -p 'Répertoire de destination: ' dest | ||
1243 | |||
1244 | # <destination> doit être un répertoire: | ||
1245 | if [ ! -d $dest ] | ||
1246 | then | ||
1247 | echo "Erreur: la destination doit être un répertoire." | ||
1248 | echo " Le cas échéant, utilisez \"mkdir $dest\"" | ||
1249 | echo " pour créer le répertoire de destination." | ||
1250 | exit 1 | ||
1251 | else # Si <destination> est un répertoire, alors pour chaque fichier | ||
1252 | # copié on incrémente le compteur. Et dès que le compteur | ||
1253 | # atteint le chiffre de 10, on sort de la boucle. | ||
1254 | for file in $files # pour chaque fichier à copier | ||
1255 | do | ||
1256 | cp $file $dest | ||
1257 | let "countfiles = countfiles + 1" | ||
1258 | if [ $countfiles -eq 10 ] | ||
1259 | then | ||
1260 | break # sortie de la boucle | ||
1261 | fi | ||
1262 | done | ||
1263 | fi | ||
1264 | |||
1265 | echo "Terminé. 10 fichiers au maximum ont été copiés dans $dest." | ||
1266 | \end{minted} | ||
1267 | \captionof{listing}{bash: copie d'un nombre limité de | ||
1268 | fichiers\label{lst:copyten}} | ||
1269 | |||
1270 | Ce script donne un exemple de code commenté. Comme on le voit, les | ||
1271 | commentaires peuvent se trouver sur des lignes isolées aussi bien que | ||
1272 | sur des lignes qui contiennent des commandes\footnote{Voir ci-dessus, | ||
1273 | \vref{sec:les-commentaires}.}. | ||
1274 | |||
1275 | Exécution du script \verb|copyten.sh|: | ||
1276 | \begin{minted}{text} | ||
1277 | [robert@kiddo courses]$ ls *.txt | ||
1278 | 01.txt 03.txt 05.txt 07.txt 09.txt 11.txt | ||
1279 | 02.txt 04.txt 06.txt 08.txt 10.txt 12.txt | ||
1280 | [robert@kiddo courses]$ ./copyten.sh | ||
1281 | Attention: ce programme copie au maximum 10 fichiers. | ||
1282 | Que souhaitez-vous copier: *.txt | ||
1283 | Répertoire de destination: Houba | ||
1284 | Erreur: la destination doit être un répertoire. | ||
1285 | Le cas échéant, utilisez "mkdir Houba" | ||
1286 | pour créer le répertoire de destination. | ||
1287 | [robert@kiddo courses]$ mkdir Houba | ||
1288 | [robert@kiddo courses]$ ./copyten.sh | ||
1289 | Attention: ce programme copie au maximum 10 fichiers. | ||
1290 | Que souhaitez-vous copier: *.txt | ||
1291 | Répertoire de destination: Houba | ||
1292 | Terminé. 10 fichiers au maximum ont été copiés dans Houba. | ||
1293 | [robert@kiddo courses]$ ls Houba/ | ||
1294 | 01.txt 02.txt 03.txt 04.txt 05.txt 06.txt 07.txt | ||
1295 | 08.txt 09.txt 10.txt | ||
1296 | \end{minted} | ||
1297 | |||
1298 | \paragraph{continue} | ||
1299 | \index[cmds]{continue|textbf} À l'inverse de \verb|break|, | ||
1300 | \verb|continue| demande à \emph{bash} d'interrompre l'itération | ||
1301 | courante mais sans quitter la boucle, puis de reprendre la boucle à | ||
1302 | partir de l'itération suivante. C'est une façon de prévoir des | ||
1303 | exceptions. Par exemple, nous pouvons modifier le script | ||
1304 | \ref{lst:copyten} comme suit: | ||
1305 | |||
1306 | \begin{minted}[linenos,highlightlines={26-31}]{bash} | ||
1307 | #!/bin/bash | ||
1308 | |||
1309 | # création du compteur de fichiers copiés. | ||
1310 | countfiles=0 | ||
1311 | |||
1312 | # On demande quels fichiers doivent être copiés. Mais avant cela, on | ||
1313 | # explique à l'utilisateur ce que fait ce programme. | ||
1314 | echo "Attention: ce programme copie au maximum 10 fichiers." | ||
1315 | read -p 'Que souhaitez-vous copier: ' files | ||
1316 | |||
1317 | # On demande la destination: | ||
1318 | read -p 'Répertoire de destination: ' dest | ||
1319 | |||
1320 | # <destination> doit être un répertoire: | ||
1321 | if [ ! -d $dest ] | ||
1322 | then | ||
1323 | echo "Erreur: la destination doit être un répertoire." | ||
1324 | echo " Le cas échéant, utilisez \"mkdir $dest\"" | ||
1325 | echo " pour créer le répertoire de destination." | ||
1326 | exit 1 | ||
1327 | else # Si <destination> est un répertoire, alors pour chaque fichier | ||
1328 | # copié on incrémente le compteur. Et dès que le compteur | ||
1329 | # atteint le chiffre de 10, on sort de la boucle. | ||
1330 | for file in $files # pour chaque fichier à copier | ||
1331 | do | ||
1332 | if [ ! -e $file ] # si le fichier à copier n'exite pas | ||
1333 | then | ||
1334 | echo "création de $file qui n'existe pas..." | ||
1335 | touch $dest/$file | ||
1336 | continue # arrêter ici et reprendre à la l. 24 | ||
1337 | fi | ||
1338 | cp $file $dest | ||
1339 | let "countfiles = countfiles + 1" | ||
1340 | if [ $countfiles -eq 10 ] | ||
1341 | then | ||
1342 | break # sortie de la boucle | ||
1343 | fi | ||
1344 | done | ||
1345 | fi | ||
1346 | |||
1347 | echo "Terminé. 10 fichiers au maximum ont été copiés dans $dest." | ||
1348 | \end{minted} | ||
1349 | \captionof{listing}{bash: copie d'un nombre limité de | ||
1350 | fichiers sans échec si le fichier source n'existe pas} | ||
1351 | |||
1352 | \begin{quoting} | ||
1353 | \textbf{Commentaire:} | ||
1354 | \begin{enumerate} | ||
1355 | \item À la ligne~30, l'instruction \verb|continue| intervient dans | ||
1356 | le cas où le fichier à copier n'existe pas (voir le test de la | ||
1357 | ligne~26). | ||
1358 | \item Dans ce cas, le fichier est créé par la ligne~28. | ||
1359 | \item Puis \verb|continue| interrompt la boucle et la reprend depuis | ||
1360 | la ligne~24. | ||
1361 | \end{enumerate} | ||
1362 | \end{quoting} | ||
1363 | |||
1364 | Voici ce que donne l'exécution de ce script: | ||
1365 | \begin{minted}{text} | ||
1366 | [robert@kiddo courses]$ ./copyten.sh | ||
1367 | Attention: ce programme copie au maximum 10 fichiers. | ||
1368 | Que souhaitez-vous copier: tchic.txt | ||
1369 | Répertoire de destination: Houba | ||
1370 | création de tchic.txt qui n'existe pas... | ||
1371 | Terminé. 10 fichiers au maximum ont été copiés dans Houba. | ||
1372 | [robert@kiddo courses]$ ls Houba/ | ||
1373 | tchic.txt | ||
1374 | \end{minted} | ||
1375 | |||
1376 | \section{Les fonctions} | ||
1377 | \label{sec:les-fonctions} | ||
1378 | Comme leur nom l'indique, les fonctions permettent d'exécuter des | ||
1379 | instructions de façon autonome dans un script. Elles peuvent être | ||
1380 | ensuite utilisées aussi souvent que nécessaire et permettent donc de | ||
1381 | réduire la taille du script. Deux formats sont permis: | ||
1382 | \begin{minted}[linenos]{bash} | ||
1383 | # Format 1 | ||
1384 | ma_fonction () { | ||
1385 | <commandes> | ||
1386 | } | ||
1387 | |||
1388 | # Format 2 | ||
1389 | function ma_fonction { | ||
1390 | <commands> | ||
1391 | } | ||
1392 | \end{minted} | ||
1393 | |||
1394 | Ces deux formats sont strictement équivalents. Le premier est le plus | ||
1395 | répandu car il rappelle ce qui se fait dans de nombreux autres | ||
1396 | langages où l'on utilise les parenthèses pour passer aux fonctions des | ||
1397 | variables, des chaînes de caractères, des paramètres optionnels ou | ||
1398 | même d'autres fonctions. Toutefois, en \emph{bash}, on ne met jamais | ||
1399 | rien entre les parenthèses qui sont purement décoratives. | ||
1400 | |||
1401 | Le script suivant permet de parvenir au même résultat que le script | ||
1402 | qui a été présenté dans le \vref{lst:countlines}: | ||
1403 | \begin{minted}[linenos]{bash} | ||
1404 | #!/bin/bash | ||
1405 | |||
1406 | echo "Entrez le nom du fichier dont vous voulez compter les lignes:" | ||
1407 | read -p 'Fichier: ' file | ||
1408 | |||
1409 | countlines () { | ||
1410 | cat $1 | wc -l | ||
1411 | } | ||
1412 | |||
1413 | if [ ! -e $file ] || [ -z $file ] | ||
1414 | then | ||
1415 | echo "Erreur: le fichier $file n'existe pas." | ||
1416 | exit 1 | ||
1417 | else | ||
1418 | numline=$(countlines $file) | ||
1419 | fi | ||
1420 | |||
1421 | if [ $numline -le 1 ] | ||
1422 | then | ||
1423 | echo "Votre fichier $file compte $numline ligne." | ||
1424 | else | ||
1425 | echo "Votre fichier $file compte $numline lignes." | ||
1426 | fi | ||
1168 | \end{minted} | 1427 | \end{minted} |
1428 | \captionof{listing}{bash: exemple de | ||
1429 | fonction\label{lst:countlines-mk2}} | ||
1169 | 1430 | ||
1431 | Pour terminer, exécutons cette nouvelle version de notre script | ||
1432 | ici appelée \verb|countlines-mk2.sh|: | ||
1433 | |||
1434 | \begin{minted}{text} | ||
1435 | [robert@kiddo courses]$ ./countlines-mk2.sh | ||
1436 | Entrez le nom du fichier dont vous voulez compter les lignes: | ||
1437 | Fichier: makefile | ||
1438 | Votre fichier makefile compte 21 lignes. | ||
1439 | \end{minted} | ||
1170 | 1440 | ||
1171 | \hfill\verb|../..| à suivre | 1441 | \hfill\verb|../..| à suivre |
1172 | 1442 | ||
1173 | \printindex[cmds] | 1443 | \printindex[cmds] |
1174 | \end{document} | 1444 | \end{document} |
1175 | |||
1176 | \item \verb|<| lit le contenu du fichier dont le nom suit et le passe | ||
1177 | en argument à la commande qui précède pour traitement. \ No newline at end of file | ||