TetaTricks/chap/shell.tex

316 lines
11 KiB
TeX
Raw Normal View History

2020-11-03 09:08:45 +11:00
\chapter{Le Shell}\index{shell}
2020-11-17 05:45:21 +11:00
\label{chap:shell}
2020-11-03 09:08:45 +11:00
2021-10-05 07:24:01 +11:00
Le \texttt{shell} est le coquillage qui isole le
MC/P\footnote{Master Control Program} des yusers.
2020-11-03 09:08:45 +11:00
En gros, hein, je vais simplifier, et me limiter aux
bricolages constructifs et/ou amusant. Il y aura du gore\index{gore}
2023-04-03 08:32:29 +11:00
aussi, parce que le shell est à la fois un interpréteur de commande
et un langage de programmation.
Ces deux notions ont beaucoup de choses en commun, comme nous
2023-10-09 06:56:41 +11:00
allons essayer de le voir. Certains qualifient le shell de
« langage de glue », et c'est une image assez pertinente.
2023-04-03 08:32:29 +11:00
Nous allons nous concentrer sur le \textsl{Bourne again shell}
(aka \texttt{bash}\footnote{aka GNU/shell ?}) qui est un des plus
répandus, du moins dans le monde Linux\index{Linux}.
Mais il en existe d'autres : sh, ksh, ash, zsh, tthsh\dots
2023-10-09 06:56:41 +11:00
Ce qui, bien entendu, pose quelques problèmes de compatibilité.
Ou alors, il faut reste \textsc{posix}, mais c'est pour le moment
une autre histoire. Parce que là, on est plutôt dans une optique
« morefun » sur l'utilisation de nos machines.
2020-11-17 05:45:21 +11:00
2020-11-03 09:08:45 +11:00
% ==============================================================
\section{Interpréteur}\index{cli}
2023-10-09 06:56:41 +11:00
Ceci est un prompt : \texttt{tth@redlady:\textasciitilde\$}.
Son petit nom est \texttt{PS1}. On peut y
2023-06-29 20:23:11 +11:00
mettre plein d'informations utiles et de \textsl{mises en forme} assez
funky\footnote{Un peu de calme, fatalerrors !} permettant
2023-10-09 06:56:41 +11:00
d'enhancer la reliability de votre UI/UX. Mais surtout il est
là pour indiquer qu'il attend vos ordres, qu'il est prèt à
interpréter vos lignes de commandes.
\begin{verbatim}
tth@redlady:~$ date --utc
Thu Oct 5 00:53:01 UTC 2023
tth@redlady:~$
\end{verbatim}
2020-11-03 09:08:45 +11:00
2024-08-09 00:33:18 +11:00
Ces ordres peuvent être des commandes internes à l'interpréteur,
d'autres seront des commandes fournies par des exécutables
externes. Pour le début, la différence n'est pas importante.
Mais comment le shell fait-il pour retrouver tous les outils
dont il a besoin ? Simplement, il connait une liste
d'endroits où aller chercher, une sorte de chemin de recherche,
c'est d'ailleurs pour ça que cette liste
est nommée \texttt{PATH}\index{PATH}.
Il est très simple de la visualiser~:
\begin{verbatim}
tth@redlady:~/Devel/TetaTricks$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
\end{verbatim}
2020-11-03 09:08:45 +11:00
% ==============================================================
2024-08-09 00:33:18 +11:00
\section{Un langage}\index{script}
2020-11-03 09:08:45 +11:00
2024-08-09 00:33:18 +11:00
Le shell est aussi, et surtout, un langage de programmation
à part entière.
Il est parfois appelé \textsl{glue-language} parce qu'il permet de
"coller" ensemble plusieurs opérations élémentaires, d'abord avec
ses opérateurs internes et ensuite par l'utilisation d'outils
extérieurs\footnote{Grep, Sed, Awk, BwBasic, Sort, Gfortran...}
2023-06-29 20:23:11 +11:00
divers. C'est \textsl{très} efficace.
2024-08-09 00:33:18 +11:00
Nous allons commencer par voir quelques notions liées à
la création d'un script exécutable, puis d'un enchainement
de commandes.
Nous passerons ensuite aux structures de contrôle, comme les
tests et les boucles.
2023-11-30 00:12:03 +11:00
% --------------------------------------------------------------
2024-09-18 03:58:33 +11:00
\subsection{Le shebang} \index{shebang} \label{shebang}
2023-06-29 20:23:11 +11:00
Le shebang, c'est ce couple de caractères \texttt{\#!} qui apparait
au tout début d'un script shell.
2024-08-09 00:33:18 +11:00
Le 'she' est l'abréviation de 'sharp', qui veut dire 'coupant' en français.
C'est
2023-06-29 20:23:11 +11:00
probablement une allusion aux cotés tranchants du \texttt{\#}.
Quand au 'bang', c'est le point d'exclamation après l'explosion
de la forkbomb.
Quand on demande au noyau\index{kernel} d'exécuter un fichier
\texttt{(man 3 exec}), il va en lire d'abord les premiers
octets. Si les deux premiers sont \textsl{0x23 0x21}, le reste
de la première ligne sera interprété pour lancer un autre exécutable,
avec un traitement particuler des options.
2020-11-03 09:08:45 +11:00
2024-08-09 00:33:18 +11:00
Et à ce momment-là des explications, on entend Serguey qui hurle
du fond de la salle « schmod777 en force ! ».
Et il a bien raison. En effet, ce fichier doit être vu comme
possiblement exécutable selon les droits 'X' qu'il a.
Il y a une commande prévue à cet effet, dont nous allons voir
l'usage à l'instant, avec la création d'un script complet~:
\begin{verbatim}
tth@redlady:~$ echo '#!/bin/bash' > foo.sh
2024-09-18 03:58:33 +11:00
tth@redlady:~$ echo 'printf "%x" 85 >> foo.sh
2024-08-09 00:33:18 +11:00
tth@redlady:~$ chmod u+x ./foo.sh
tth@redlady:~$ ./foo.sh
55
tth@redlady:~$ cat foo.sh
#!/bin/bash
printf "%x\n" 85
tth@redlady:~$
\end{verbatim}
2020-11-03 09:08:45 +11:00
% ==============================================================
2021-08-01 23:53:41 +11:00
\section{Le pipeline}\index{pipeline}\label{pipeline}
2023-06-29 20:23:11 +11:00
Une invention géniale, dont vous pouvez voir un exemple d'utilisation
par un gadget sonore en page \pageref{say-uptime} et
2021-08-01 23:53:41 +11:00
un bout de code C en page \pageref{filtre-unix}.
2023-10-09 06:56:41 +11:00
Exemple rapide, où la commande \texttt{uptime} envoie sa sortie dans
le tuyau, et la commande \texttt{tr} va lire le tuyau pour
son entrée~:
2023-06-29 20:23:11 +11:00
\begin{verbatim}
2023-10-09 06:56:41 +11:00
$ uptime | tr ' ' 'X'
2023-06-29 20:23:11 +11:00
X09:22:29XupX33Xdays,X14:00,XX8Xusers,XXloadXaverage:X0.12,X0.17,X0.17
\end{verbatim}
2023-10-09 06:56:41 +11:00
Bien entendu, on peut utiliser plusieurs tuyaux pour construire
2024-09-29 05:25:02 +11:00
une chaine de traitements%
\footnote{La chaine de compilation \textsc{eqn/tbl/roff} est un bon exemple}.
2023-10-09 06:56:41 +11:00
On peut même « intercepter » ce qui transite par un des tuyaux.
\begin{verbatim}
2024-09-29 05:25:02 +11:00
tth@redlady:~/Devel/TetaTricks$ date | tee foo.txt |
tr 'EASLeasl' '34573457'
W3d 53p 25 16:07:01 C35T 2024
tth@redlady:~/Devel/TetaTricks$ cat foo.txt
Wed Sep 25 16:07:01 CEST 2024
2023-10-09 06:56:41 +11:00
\end{verbatim}
2024-09-29 05:25:02 +11:00
% ==============================================================
% new Wed Sep 25 14:00:07 UTC 2024
\section{L'environnement} \index{environ}
Commençons par une petite histoire.
Un jour\footnote{été 2024 ?}, je suis tombé par un hasard
improbable sur une variable d'environnement nommée
\textsc{hostname}. Qui contenait précisément "redlady" !
Tout bien.
Alors, quelques jours avant, vers 2006, je l'ai utilisée
dans un bout de code en C, que j'avais depuis bien
bien longtemps oublié au fond
d'une 8" hard-sectored.
Et là, ça ne marche pas comme je l'espérais.
Voyez ce bout de code~:
\begin{verbatim}
char *nom = "HOSTNAME";
printf("%s -> %s\n", nom, getenv(nom));
\end{verbatim}
Il me renvoit \texttt{HOSTNAME -> (null)}.
Krkrkr.
2023-10-09 06:56:41 +11:00
% ==============================================================
2023-11-30 00:12:03 +11:00
\section{Structures de contrôle}
2024-09-29 05:25:02 +11:00
Les plus importantes sont là : le choix, la boucle, l'attente,
le \textsc{goto}\index{goto} calculé, la sélection,
\textsl{make your choice}.
2024-08-09 00:33:18 +11:00
2023-11-30 00:12:03 +11:00
% --------------------------------------------------------------
\subsection {Les tests}
2024-09-18 03:58:33 +11:00
Deux éléments sont ils égaux ? Et d'abord, ces deux éléments
sont-ils comparables ?
2023-11-30 00:12:03 +11:00
% --------------------------------------------------------------
\subsection {Les boucles}
2024-09-18 03:58:33 +11:00
Exemple très simple~:
\begin{verbatim}
for foo in A B C D
do
echo ${foo}
done
\end{verbatim}
Autre exemple, un peu moins simple~:
\begin{verbatim}
for foo in $(seq 0 37 133)
do
printf "foo = %3d\n" ${foo}
done
\end{verbatim}
2023-11-30 00:12:03 +11:00
% ==============================================================
2023-10-09 06:56:41 +11:00
\section{Les fonctions}
Une bonne manière de rendre votre code modulaire, et de réutiliser
des bouts de code à volonté depuis plusieurs programmes.
2024-09-29 05:25:02 +11:00
Une fonction peut accepter des paramètres, qui seront
connus sous les petits noms de
\texttt{\$1 \$2 ... \$n}.
2023-10-09 06:56:41 +11:00
2024-09-29 05:25:02 +11:00
Voici un fichier contenant quelques fonctions~:
2023-10-09 06:56:41 +11:00
\lstinputlisting{code/shell/fonctions.sh}
2024-09-29 05:25:02 +11:00
Pour les utiliser, il faut d'abord les charger dans le shell courant.
C'est la directive \texttt{source}\index{source} qui s'en charge~:
2023-10-09 06:56:41 +11:00
\lstinputlisting{code/shell/demofonctions.sh}
2024-09-29 05:25:02 +11:00
XXX expliquer "source" \index{XXX}
2023-10-09 06:56:41 +11:00
% ==============================================================
% https://bwog-notes.chagratt.site/2023/le-heredoc/
\section{Heredoc}
2023-11-30 00:12:03 +11:00
Un nom bien difficile à traduire, peut-être par « document en place » ?
2024-09-18 03:58:33 +11:00
C'est un moyen simple et efficace de mettre des données textuelles
2024-09-29 05:25:02 +11:00
(comme des commandes pour un logiciel particulier)
2024-09-18 03:58:33 +11:00
dans un script afin de les envoyer dans le \textsl{stdin} d'un
logiciel. Par exemple, quelques commandes pour générer un
graphique avec Gnuplot\index{gnuplot} sur la console \textsl{dumb}.
2023-10-09 06:56:41 +11:00
\lstinputlisting{code/shell/heredoc.sh}
2024-09-18 03:58:33 +11:00
Après le \textsl{shebang}, nous avons la création de la variable
pour le titre,
et ensuite l'appel à Gnuplot avec la redirection
\texttt{$<<$ \_\_EOC\_\_} % bug affichage "<<"
qui va envoyer sur le stdin de Gnuplot la suite du
script shell (des commandes gnuplot), jusque au marqueur de fin,
qui est \texttt{\_\_EOC\_\_} dans notre cas.
... et la démonstration~:
2023-10-09 06:56:41 +11:00
\begin{verbatim}
2024-09-18 03:58:33 +11:00
tth@redlady:~/Devel/TetaTricks/code/shell$ ./heredoc.sh
Here Doc (9946)
1 +-------------------------------------------------------------+
| + + + + + + + + + |
| 0.7*sin(x) ******* |
| ****** ****** |
0.5 |-+ ** ** ** ** +-|
| ** * * ** |
| ** ** ** ** |
| ** ** ** ** |
|* ** ** *|
0 |-+ * * +-|
| ** ** |
| * * |
| * * |
-0.5 |-+ ** ** +-|
| *** *** |
| ******* |
| |
| + + + + + + + + + |
-1 +-------------------------------------------------------------+
0 1 2 3 4 5 6 7 8 9
2023-10-09 06:56:41 +11:00
\end{verbatim}
Je pense que l'exemple est assez parlant.
Pour un exemple plus complet, toujours avec gnuplot, c'est vers la
page \pageref{chap:gnuplot}.
2023-06-29 20:23:11 +11:00
% ==============================================================
\section{Les \textsl{locales}}
\index{locales}
% new: Mon Apr 17 10:54:45 UTC 2023
Quelle sont les différences entre \texttt{en\_US.UTF-8} et
\texttt{C.UTF-8} ?
2021-02-04 19:56:36 +11:00
% ==============================================================
2024-09-18 03:58:33 +11:00
% https://wiki.fiat-tux.fr/books/d%C3%A9veloppement/page/ajouter-des-couleurs-a-ses-scripts-shell
\section{Écrire en couleur} \index{ANSI} \index{escape}
\begin{verbatim}
BLACK='\033[0;30m'
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[0;37m'
\end{verbatim}
% ==============================================================
2020-11-03 09:08:45 +11:00
\section{Questions à voir}
2020-11-17 05:45:21 +11:00
\begin{itemize}
\item le traitement des chaines de caractères\dots
2023-06-29 20:23:11 +11:00
\item la gestion des co-routines\dots
2020-11-17 05:45:21 +11:00
\end{itemize}
2020-11-03 09:08:45 +11:00
% ==============================================================