Précédent
 
Suivant

Le shell Bash
II

 

11) La variale système PATH

Une commande shell peut être lancer directement par son nom tel que date, et elle peut aussi être lancer comme un programme à partir de son chemin complet. Pour connaître où se trouve le programme de cette commande, tapez type -a date et la réponse sera /bin/date. Ainsi la commande date est identique à la commande /bin/date et elle retourne la date actuelle : jeu. 30 mars 2023 17:23:02 CEST.

Le shell utilise la variable système PATH qui contient une liste de répertoires séparés par des deux-points. Lorsque le shell rencontre un nom alors qu'il s'attend à rencontrer une commande shell ou un programme à exécuter, il regarde si ce nom existe dans les répertoires listés dans la variable PATH et il retourne le premier rencontré qui a les droites d'exécution pour l'exécuter.

Il n'y a pas de différence de nature entre un programme et une commande shell. Tous deux peuvent prendre de multiple options et peuvent rediriger leurs entrée-sorties en utilisant une même syntaxe.

Mais le comportement diffère pour les arguments. Lorsque le shell rencontre un nom alors qu'il s'attend à rencontrer un fichier comme argument, il regarde seulement si ce nom existe dans le répertoire courant.

Pour alléger l'écriture, on peut ajouter parfois au PATH le repertoire courant désigné par le point, ce qui se fait par l'intruction PATH=.:$PATH et qui nous permet par la suite d'appeler comme une commande les programmes se trouvant dans le répertoire courant juste par leur nom plustôt que par leur chemin.

12) Périphériques (devices en anglais)

L'intérêt démonstratif du shell Bash tient dans l'étonnante simplicité, à créer des programmes Basch rudimentaires avec boucles et répétition, à les appeller en transmettant des arguments en ligne de commande et en redirigeant leurs canaux entrées et leur cannaux de sorties, à créer des fichiers, à exécuter des processus en arrière plan, à créer des tubes asynchrones et synchrones, à utiliser des terminaux pouvant tester immédiatement tous ces procédés scripturaux, et qui peuvent être utilisée de façon distante via une connexion sécurisée ssh. Et ces flux de données que sont les tubes peuvent transiter via l'Internet, grace aux périphériques de type sockets en utilisant le protocole tcp ou udp.

12.1) Type de périphérique

L'une des grandes idées d'UNIX est l'unification des opérations d'entrée-sortie, quelles s'appliquent sur un fichier ou sur un périphérique. Les mêmes appels système d'entrée-sortie servent à ouvrir, lire, écrire et fermer un périphérique comme s'il s'agissait d'un fichier. Sous linux, "tout est fichier" sauf s'il s'agit d'un processus, mais les fichiers sont de différents types caractérisés par la première lettre de leur permission telle qu'elles apparaissent dans la sortie ls -l

-
   Regular file   Fichier normaux
d
   Directory   Réperoire
l
   Symbolic link   Lien symbolique
b
   Block device   Périphérique de blocs
c
   Character device   Périphérique de caractères
s
   Socket   Connexion
p
   Named pipe   Tube nommé

Les fichiers binaires, les fichiers textes et multimédia sont tous des fichiers normaux (-). Les répertoires (d), sont des dossiers répertoriant une liste de fichiers et constituent donc les noeuds de l'arborescence des fichiers. Les liens symboliques (l), sont des liens vers d'autres fichiers pouvant se trouver à un autre endroit dans l'arborescence. Les périphériques de blocs (b), transfèrent des blocs de données binaires (exemple : disque dur, lecteur dvd,...). Les périphériques de caractères (c), transfèrent des caractères. Les périphériques de connexion (s), transfèrent des données via une connexion réseau. Et les Tubes nommés (p) sont des flux de données qui ont un nom.

12.2) Périphériques du processus

Chaque processus possède trois fichiers périphériques initialement ouverts :

Chaque fichier ouvert par le processus se voit affecté un descripteur de fichier allant de 0 à 1024, que nous appellons canaux. Le numéro descripteur ou du canal est une autre façon plus courte de désigner le fichier relatif au processus jouant le rôle d'entrée ou de sortie, dans les opérations d'entrées-sorties. Chaque descripteur, par exemple le descripteur 3 désigne un fichier ouvert, dont le nom pour le processus en question est /dev/fd/3, et que nous appellons le canal n°3 du processus. Il faut bien comprendre que le même nom lu par un autre processus cousin désignera un autre fichier.

Dans une console telle que TTY3, l'entrée standart /dev/stdin qui est identique au device /dev/fd/0 qui correspond à l'entrée du périphérique bidirectionnel /dev/tty3 qui est identique au périphérique alias /dev/tty lorsque la console à le focus, et qui, si elle n'a pas été redirigée, correspond au clavier.

Il existe un périphérique spécial qui sert de poubelle /dev/null. Toutes les données qui y sont envoyés sont simplement ignorées par le système. Et si vous tentez de lire depuis ce trou noir à caractères, vous recevez le signal de fin de fichier. Ce signal de fin de fichier peut être saisie directement au clavier <Ctl>+D. Dans certain il faut arréter le processus émetteur au premier plan, en saisissant au clavier <Ctl>+C pour fermer la transmission.

12.3) Tube nommée

Le descripteur de fichier possède en plus deux curseurs ; un curseur qui indique où en est la lecture, et un curseur qui indique où en est l'écriture. Et deux comportement sont possible. Soit on lit le fichier ligne par ligne par le début et le curseur avance d'une ligne après chaque lecture d'une ligne. Soit on lit le fichier ligne par ligne par la fin et on recule le curseur d'une ligne. Le premier comportement correspond au fichiers normaux. Le second comportement correspond aux Tubes nommés appelé aussi fichier FIFO (First In, First Out). C'est ce dernier qui est utilisé pour communiquer entre processus de façon synchrone (bloquant) ou asynchrone (non bloquant).

Le fichier qui représente le flux de données reliant deux processus est un fichier FIFO. On peut créer un tel fichier f comme suit :

mkfifo f

On peut lui assigner un descripteur comme suit

3<>f

Mais la portée de cette prescription ne s'applique qu'à la commande en cours. Si on veut étendre la portée à tous le programme en cours et aux processus fils, alors on utilise l'instruction suivante :

exec 3<>f

Cela rend permanent l'assignation du descripteur n°3 tant que le celui-ci n'est pas réassigné. Mais comme nous souhaitons utiliser des canaux de communication entres processus qui soit propres aux processus, on ne peut pas fixer le nom de ce fichier qui doit être différent pour des processus de familles distinctes. On utilise pour cela mktemp -u qui retourne un nom libre de fichier temporaire, et on crée un tube nommé avec ce nom, puis on lui assigne un descrippteur. Puis il n'est pas nécessaire de garder ce fichier qui constitue une copie du flux surfaite, c'est pourquoi on le supprime après.

F=$(mktemp -u)
mkfifo $F
exec 3<> $F
rm $F

Ainsi le processus à ouvert de façon pérenne son canal n°3 en lecture écriture en mode FIFO. Il peut créer des processus fils qui vont pouvoir utiliser ce canal.

ouverture canal 3man source

 

 

 

 

 

 

12.3) Redirection d'entrées-sorties

Le processus est comparable à la notion abstraite de machine possèdant plusieurs canaux d'entrée et plusieurs canaux de sortie. Le shell va permettre de raccorder ces canaux d'entrées et de sorties d'une manière simple. Chaque processus possède trois fichiers périfériques ouverts par défaut, stdin (ouvert en lecture), stdout (ouvert en écriture), stderr (ouvert en écriture), de numéros descripteurs respectifs 0,1,2. Et il est possible d'utiliser d'autres numéros descripteurs allant de 0 à 1024 et pouvant désigner d'autres fichiers périphériques propre au processus et que nous appellons canaux. Les processus fils héritent de ces descripteurs

Les spécifications de redirection des sorties de la commande en cours se font à l'aide de l'opérateur > qui possède deux arguments.

On peut ouvrir un canal en le redirigeant soit sur un fichier ou soit sur un autre canal ouvert. Et pour ouvrir un nouveau canal sans le rediriger, on procède ainsi :

exec 3<>f3
exec 4<>f4
exec 5<>f5

Cela crée 3 fichiers périférique f3, f4, f5 correspondant au canaux 3.4.5. Considéons la commande suivante :

4>&1  3>&4  3>f  ./a

Cela ouvre le canal 4 qui est dérigé vers le 1. Puis cela ouvre le canal 3 qui est dirigé vers le 4. Puis une copie du canal 3 est également redirigée sur le fichier f. puis le programme a est executé, et c'est lui qui procédera aux échanges de données sur ces différents cannaux. Lorque le premier argument est manquant, par défaut c'est le 1. Ainsi le symbole  "  >" et idendique à "1>"

à chaque nouvelle commmande, un nouveau processus est créée qui hérite des canaux définis pour le bloc de code en cours ou pour la console et qui sont initialement 0, 1, 2, ou 0 correspondant à l'entrée clavier, et le 1 et le 2 correspond à des sorties vers l'écran. Par exemple :

>f echo Bonjour; >>f echo Au revoir;

{ echo Bonjour; echo Au revoir;} >f

 

 

 

 

Une commande peut spécifier plusieurs tels redirections.

Les spécifications de redirection des entrées de la commande en cours se font à l'aide de l'opérateur < qui possède pareillement 2 arguments

 

 

 

 

 

3>&4
Redirige le canal n°3 vers le canal n°4
5> f
Redirige le canal n°5 vers le fichier f

 
6<&1
Redirige le canal n°1 vers le canal n°6
8<f
Redirige le fichier f vers le canal n°8

 

 

 

 

Les spécifiations de redirection sont les suivantes, où f est un fichier quelconque :

> f
Redirige la sortie standard stdout vers le fichier f.
>> f
Redirige la sortie standard stdout vers le fichier f en mode "ajout à la fin".
< f
Redirige l'entrée standart stdin depuis le fichier f.

Et ces spécifications sont identiques au suivantes qui précisent le canal de sortie par défaut :

1> f
1>> f
1< f

 

 

 

>
 
>> f
 
< f
 

 

 

 

 

  

>>f

<f

3>f

3<f

 

 

 

 

Considérons des programmes p, q, a, b, c et des fichiers f, g, placés dans le courant. Si le point à étét ajouté au PATH, le shell peut exécuter le programme a en l'appellant juste par son nom :

 
Lorsque le PATH contient "."
./a
a

Il peut rediriger sa sortie standart vers le fichier f  désigné juste par son nom puisque situé dans le répertoire courant, en mode réécriture ou en mode ajout à la fin, grâce aux symboles > et >>. Et si le fichier n'existe pas :

./a >f
a >f
./a >>f
a >>f

Il peut raccorder son entrée standart à partir d'un fichier f  désigné juste par son nom puisque situé dans le répertoire courant :

./a <f
a <f

La redirection peut préciser le numéro de descripteur. Ainsi les instructions suivantes sont identiques :

./a   <f   >g
a   <f   >g
./a   0<f   1>g
a   0<f   1>g

 

 

Pour fermer la sortie de descripteur n°3 :

exec 3>&-

 

 

Le bash peut manquer un certain nombre de commande qui peuvent être programmé dans des scripts Perl, un langage qui a été trés utilisé pour cela. On ajoute deux commandes au shell que sont seek et geek. Une commande pour déplacer le curseur d'un descripteur de fichier, d'un nombre entier d'octets. Pour cela on ajoute dans le répertoire /usr/local/bin/ qui est bien listé dans la variable PATH, le fichier seek et le fichier geek suivants :

seek
perl -e "open(FD,\">&$1\"); seek(FD,$2,$3);"

geek
perl -e "open(FD,\">&$1\"); print tell(FD),\"\n\";"

Ce sont des commandes systèmes génériques qui ne nécessite pas de shebang. Par exemple considérons un fichier ouvert de descripteur n°3 :

geek 3
Retourne la position du curseur du descripteur n°3 en nombres d'octets.
seek 3 0 0
Met le curseur du descripteur n°3 sur l'octet numéro 0 à partir du début.
seek 3 5 1
Déplace le curseur du descripteur n°3 de 5 octets.
seek 3 -5 1 Déplace le curseur du descripteur n°3 de -5 octets.
seek 3 -5 2 Déplace le curseur du descripteur n°3 de -5 octets à partir de la fin.

L'inconvenient est que un caractère unicode en utf8 peut avoir une taille de 1, 2 ou 3 octets, et que le déplacement du curseur étant en nombre d'octets, celui-ci peut découper un octet en deux.

12) Commandes (read, cat, tac, write, echo)

 

 

 

Les opérateurs && et || (associativité à gauche) sont de priorité plus forte que ; et &

 

 

mots réservés

if then elif else fi time
for in until while do done
case esac coproc select function
{ } [[ ]] !

boucles :

until com1; do com2; done

while com1; do com2; done

for x; do com1; done

for x in $L; do com1: done

for x in $(com1); do com2; done

for ((x=1; x<=10; x++)); do com1; done

for ((a=1, b=1; a<=10; a++,b++)); do com1; done

break

break 3

continue

continue 3

if com1
then com2
elf com3
else com4
fi

case w in
patern | pattern ) comd1; comd2 ;;
patern | pattern ) comd1; comd2 ;;
esac

( com1; com2 ) crée un sous-shell
{ com1; com2; }

 

coproc D { com1; com2; }

Le coprocessus exécute { com1; com2; }
D[0] est le numéro du canal de sortie du coprocessus
D[1] est le numéro du canal d'entrée du coprocessus
D_PID contient le PID du coprocessus

 

case $x in
[0-9]) com1;;
"aze" | "ritchi") com2;;
[[:lower:]]) com3;;
[[:upper:]]) com4;;
*) com5;
esac

${#x} longueur de la chaine x.

${x:7} Après les 7 premiers caractères.
${x: -4} Après les 4 derniers caractères.
${x:7:3} Les 3 premiers caractères après les 7 premiers caractères.
${*:2:3} affiche 3 paramètres de position en commençant per le deuxième.

 

RANDOM=1

$RANDOM

source ./a toto titi
.  ./a toto titi

eval arguments
eval $x

exit
exit n

export -f

 

function f { echo $1; }
f () { echo $2; }

echo x{a,b}y; echo xay xby;

 

 

ls   1> f   2>&1     (Le canal 2 et 1 réécrivent le fichier f)

ls   2>&1   1>f     (le canal 2 s'affiche à l'écran, le cannal 1 réécrit le fichier f )

 

3.2) Caractères spéciaux (*, ?, ~, $, ", ', \, =)

*
Étoile
Se remplace par n'importe quelle chaine de caractère même la chaine vide.
?
Point d'intérogation
Se remplace par exactement un caractère quelconque.
~
Tilde
Se remplace parle chemin complet du répertoire personnel de l'utilisateur courant.
.
Point
Se remplace par le répertoire courant.
..
Double point
Se remplace par le répertoire parent du répertoire courant.
$
Dollar
Par exemple, $toto se remplace par le contenue de la variable toto.
"
Guillemet
Délimiteurs de chaine de caractères interprétant les caractères $.
'
Quote

Délimiteurs de chaine de caractères. Empêche l'interprétation de tous les caractères spéciaux.

( )
Parenthèse
Lance un groupe de commande dans un sous-shell
\
Antislash
Caractère d'échapement. Pour évoquer ces caractères sans qu'ils agissent,
il suffit de les préfixer du caractère d'échappement.

 

 

 

10) Les arguments d'appel

Si on lance le programme p avec 3 arguments comme suit, appelés les arguments d'appel ou l'entrée ligne.

p ga bu zo

Alors dans le programme p les variables $1, $2, $3 vont récupérer ces arguments :

echo $1   retourne ga
echo $2   retourne bu
echo $3   retourne zo
echo $#   retourne 3
echo $*   retourne ga bu zo

"ga bu zo" constitue l'entrée ligne ou d'appel du programme p. Il est possible de redéfinir cette entrée au sein même du programme grace à la commande set ga bu zo. Cette commande va affecter les variables $1, $2, $3, $#, $* pareillement. Puis la commande shift retire le premier argument en décallant tous les autres. Ainsi

shift
echo $1   retourne bu
echo $2   retourne zo
echo $#   retourne 2
echo $*   retourne bu zo

11) Commandes d'affectation (=, $, =$(), read, echo)

Les opération d'affectation se fait à l'aide du signe = sans espace :

x=toto  change la valeur de x en toto.
x="ga bu zo" change la valeur de x en la chaine ga bu zo.

L'expression $x est remplacée par ce que contient x où les succession d'espaces, de tabulations, et de saut de ligne, sont réduites à chaque fois en un seul espace séparateur. echo $x   affiche la valeur de x qui vaut ici ga bu zo. Par ailleurs, les caractères de délimitation de chaine ne s'affichent pas sauf s'ils succèdent le caractère d'échapement \ auquel cas il ne sont plus délimitateur de chaine de caractères. L'entrée en ligne d'un programme p peut être transmis par une variable x comme suit :

./p $x   exécute le programme p avec comme entrée ligne ce que contient x.

Une variable x peut récupérer la sortie standard du programme p avec l'instruction suivante :

y=$(./p $x)    exécute la commande entre parenthèse qui produit une chaine de caractère sur sa sortie standart qui est stocker dans la variable y.

Une variable x peut récupérer le contenu du fichier f avec l'une ou l'autre de ces instructions :

x=$(<f)
x=$(cat f)

La commande read peut lire une ligne de l'entrée standart. Et elle peut connecter son entrée standart sur une autre entrée tel que l'entrée de descripteur n° 5 :

read x <&5

12) Commandes shell (<<<, xargs)

Le programme p peut prendre comme entrée standard une chaine de caractère directement comme suit :

p <<< ga bu zo

Et on peut utiliser une variable intermédiaire x="ga bu zo" comme suit :

p <<< $x

L'instruction est équivalente à

echo $x | p

La commande xargs p exécute le programme p avec comme arguments d'appel ce qui est apportée par l'entrée standart. Cela permet de remplacer la liste des arguments de p par l'entrée standart de xargs.

xargs p <<< ga bu zo est équivalent à p ga bu zo

 

 

 

 

 

 

----- 25 mars 2023 ----

13) Commandes shell (eval, exec)

La commande eval $x   exécute l'instruction shell mémorisée dans la variable x, sans lancer un sous-shell.

La commande exec p exécute le programme p à la place du shell en cours.

11) Commande <(...) et >(...)

a <(b; c) crée un fichier temporaire qui récupère la sortie standard du programme entre parenthèse b; c et ce fichier est une opérande dans l'appel du programme a

a<  <(b; c) crée un fichier temporaire qui récupère la sortie standard du programme entre prarenthèse b; c et puis le redirige comme entrée standard du programme ./a

a >(b; c) crée un fichier temporaire qui va constituer l'entrée standard du programme entre prarenthèse b; c et ce fichier est une opérande dans l'appel du programme ./a

a>  >(b; c) crée un fichier temporaire qui va constituer l'entrée standard du programme entre parenthèse b; c et ce fichier se racorde à la sortie standard du programme ./a

12) Commandes shell (echo, sort, tee, cat, tac, xargs, eval, $(), exec)

La commande echo prend ses arguments d'appel et les renvois dans la sortie standard.
echo Bonjour   va produire Bonjour sur la sortie standart qui est par défaut branché sur le périphérique de la console, et donc va s'afficher.

La commande sort va lire l'entrée standart, puis trier les lignes et les envoyer sur la sortie standart.
sort <f  >g   va lire le fichier f, trier les lignes, et les mettre dans le fichier g.
Si la commande sort à une opérande, celle ci désigne le nom du fichier qui sert d'entrée.
sort f   va lire le fichier f, trier les lignes, et les les envoyer sur la sortie standart.

La commande tee va lire l'entrée standart ligne par ligne et les renvoyer sur la sortie standart.
Si la commande tee à des opérandes, ceux-ci désignent les noms de fichier sur lesquel sera enregistré une copie de ce qui est envoyé sur la sortie standart.
tee f g   va lire ligne par ligne l'entrée standart, trier les lignes, et les les envoyer sur la sortie standart en en faisant une copie sur le fichier f et sur le fichier g.

La commande cat va lire l'entrée standart ligne par ligne et les renvoyer sur la sortie standart.
Si la commande cat à des opérandes, ceux-ci désignent les noms de fichier qui servirons d'entrés successives.
cat f g   va lire les fichiers f puis g et réenvoyer leur contenue sur la sortie standart.

 

 

14) Terminaux (tty) et redirection

Souvent le raccourci clavier <Ctl>+<Alt>+t ouvre un terminal dans l'interface graphique. Sinon allez dans le lanceur de programme chercher le terminal. La commande tty affiche le nom du périphérique du terminal qui est de la forme /dev/pts/5

Il est possible d'écrire sur un autre terminal d'adresse /dev/pts/4

echo Bonjour > /dev/pts/4

Il est possible d'écrire sur plusieurs sortie d'adresse /dev/pts/4 et sur les fichiers f et g :

echo Bonjour | tee -a  /dev/pts/4  f  g

Le shell en cours d'exécution à une entrée standard n°0, qui est le clavier et une sortie standart n°1 qui est l'écran. Ces canaux peuvent être redirigé facilement :

exec 3>&1

Cette commande crée ou redirige si déjà existant, dans le shell en cours d'exécution, le canal de sortie n°3 vers la sortie standard. Délors le canal n°3 existe. Si on envoie des données sur le canal n°3, celles-ci vont être transférées sur le canal n°1 et donc vont apparaitre à l'écran :

echo Bonjour >&3   cela affiche Bonjour

On peut aussi rediriger la sortie du shell en cours sur le fichier f, par la commande suivante :

exec 3>&1
exec > f
Pour annuler les deux instructions précèdentes : exec >&3

Pour fermer un canal n°123 : exec 123>&-

15) Pipe

Le processus est comparable à la notion abstraite de machine. Il possède deux entrées : le canal 0 et la ligne de commande d'appel. Il possède deux sorties : le canal 1 et le canal 2 réservé pour les messages d'erreur.

Le pipe "|" permet de connecter la sortie standart d'un processus avec l'entrés standart d'un autre processus.

./a | ./b

C'est similaire à l'instruction suivante à part que l'execution de ./b se fait dans un autre shell dans le cas du pipe :

./a  >  >( ./b )

Et il est possible de faire des redirections en utilisant à la place du symbole > par exemple le symbole 3>&4 et à la place du symbole < par exemple le symbole 92<&23 :

./a 3>&4 ./b   envoit la sortie n°3 du programme a vers l'entrée n°4 du programme b

./a 5<&6 ./b   envoit la sortie n°6 du programme b vers l'entrée n°5 du programme a

Le pipe ne relie que la sortie standard d'un coté à l'entrée standard de l'autre coté (qui s'exécute dans un processus fils). Il peut être utilisé pour fair un raccordement entre par exemple une sortie n°3 d'un coté et une entrée n°5 de l'autre coté comme suit :

./a 3>&1 | ./b 5<&0

 

---- 22 mars 2023 ----

 

 

 

 

 

./a  >  >(tee  >(cat  >&3))

 

Il peut rediriger sa sortie numéro 1 et 2 vers l'entrée numéro 0 d'un autre programme b grâce au symbole pipe | :

./a | ./b

On crée d'autre descripteure de fichier en utilisant des fichiers temporaires :

F=$(mktemp)    Crée un fichier temporaire et retourne son nom dans F
exec 3> "$F"     Crée le descripteur n°3 d'écriture sur le fichier temporaire.
exec 4< "$F"     Crée le descripteur n°4 de lecture sur le fichier temporaire.
rm -f "$F"     Supprime de force le fichier temporaire. (Tube asynchrone en mémoire vive seulement)

echo "Bonjour" >&3 Envoi la chaine Bonjour sur la sortie n°3 qui alimente le tube en question
cat <&4     Lit ce qu'il y a sur le canal n°4 provenant du tube en question. Cela Retourne Bonjour

Delors on peut utiliser les déscripteurs 3 et 4. Et procédé à des redirections grace aux symbole 239>&54

./a  3>&4  2>&4

./a 1>/dev/null 3>&0 | ./b

La commande xargs prog éxecute la commande prog avec comme arguments d'appel ce qui est produit par l'entré standart. Cela permet de remplacer la liste des arguments de prog par l'entrée standart de xargs. Ainsi un processus possède deux entrées qui peuvent être tubées, l'entrée standart /dev/stdin de numéro descripteur 0 et l'entrée en ligne de commande grace à xargs.

Et il possède deux sorties tubées, la sortie standart /dev/stdout de numéro descripteur 1 et la sortie de message d'erreur /dev/stderr de numéro descripteur 2. Et il possède un code de sortie qui est une valeur d'un octet que l'on utilise comme valeur booléenne vrai si égale à zéro et valeur booléenne fausse dans les autre cas. Puis on créer facilement des tubes synchrones ou asynchrones suplémentaires, de descripteur 3, 4, 5, 6, ..., jusqu'à 1024, utilisables par tous les processus fils. Puis on crée des tubes nommés qui sont autant de moyen simple de communication entre processus.

10) Première approche des scripts bash

Les commentaires sur une ligne commence par un dièse # si c'est le premier caractère de la ligne (à l'exception du shebang) ou par un espace puis dièse si le commentaire ne commence pas en début de ligne.

Les instructions Bash sont séparées séquentiellement par des point-virgule ; ou par un saut de ligne.

 

11) Première approche de la console

après avoir ouvert une session sur une console. Le processus en cours assure l'interactivité du terminal, et certains caractères spéciaux aurons une action spécifique sur la console, pour bien le percevoir, on utilise l'outils od qui code et décode tous les caractères.

echo x | od -t x1 -A n
78 0a

echo -n x | od -t x1 -A n
78

echo -en "\n\r | od -t x1 -A n

Pour saisire dans un terminal le caractère saut de ligne sans exécuter la commande : <Ctl-v> <Ctl-j>, Et si on est dans une chaine délimitée ou une portion de code qui débute par "{", la touche entrée fera un saut de ligne sans exécuter la commande car en attente de la délimitation de fin de chaine, ou de fermeture de la portion de code "}".

Dans le shell Bash, pour exécuter un programme il suffit d'écrire son nom complet suivis pas ses arguments séparés par des espaces ou tabulations. Mais, si le programme fait partie des outils shell, il peut être appelé simplement par son nom, ce mécanisme utilise la variable globale PATH qui sera vue plus-tard.

echo Bonjour le monde !

/bin/echo Bonjour le monde !

Chacune de ces instructions produira Bonjour le monde ! et passera à la ligne suivante sauf si l'option -n est présente :

echo -n Bonjour

Les arguments d'un programme sont de deux types : options ou opérandes. Les options commences par un tiret suivi d'une lettre puis sont suivi éventuellement d'un unique paramètre. Puis viennent et après les options les opérandes.

11) Convention POSIX

Le standart POSIX réunit de nombreuses conventions auquelles se conforme tout programme normalisé. C'est une forme d'héritage d'UNIX qui est reprise quasiment tel quel et qui précise ici une syntaxe du shell qui doit être prise en compte par tout programme normalisé :

1- Le nom d'un programme doit commencer par une minuscule. Et s'il est un outils qui a vocation à intégrer le shell, il doit être écrit tout en minuscule.

2- Le nom d'une option est une lettre unique ou un chiffre unique, préfixé par un tiret.

3- Les options qui n'attendent pas de paramètre doivent pouvoir être regroupées derrière le même tiret.

4- Les options distinctes peuvent être spécifiés dans un ordre quelconque à moins qu'elles soient exclusives, et dans ce cas toute option annule les options précédentes qui lui sont exclusives.

5- Dans le cas d'une option attendant un paramètre, le paramètre doit être séparé de l'option par un espace. Et dans certain cas il peut être accolé à l'option.

6- Le paramètre est un argument, une suite de caractères qui ne comprend pas de caractère séparateur en dehors de chaine délimité. Lors de l'enregistrement, les délimitations de chaine sont enlevés.

7- Toutes les options doivent précéder les opérandes sur la ligne de commande.

8- Le paramètre peut correspondre à une liste de paramètres. Et dans ce cas il se décompose dans une chaine délimité en plusieurs paramètres séparés par des espaces, ou bien il se décompose en une liste de paramètres séparés par des virgules sans espace.

9- Le premier argument qui n'est pas une option ni un argument d'option constitue la première opérande. Les arguments suivants sont traité comme des opérandes, même s'ils commencent par le caractère tiret -.

10- Les options répétées avec paramètre correspondent à une même option avec comme paramètre la liste concaténée des paramètres dans l'ordre de leur apparition.

11- Si un argument peut être identifié selon les Directives 2 à 7 comme une option, ou comme un groupe d'options alors il doit être traité comme tel.

12- Les options longues commmence par deux tirets et un nom, et ne peuvent pas être regroupés.

13- Un programme qui a vocation à intégrer le shell doit prévoir une option longue pour chacune des options courtes.

14- Dans le cas d'une option longue attendant un paramètre, le paramètre doit être séparé de l'option longue soit par un espace ou soit par le signe égal =.

15- Les options longues ne respectent pas l'alinéa 9 et peuvent apparaitre après des opérandes.

On veut proposer une syntaxe beaucoup plus pratique et riche, et finalement moins arbitraire. Comme nous avons besoin de bâtir sur des fondations existantes, nous n'allons pas modifier celle-ci mais simplement les adapter par simple perfectionnement syntaxique des données transportée. Les tubes ne transporteront plus de simples caractères ou de simples mots, mais des termes. Les données ne seront plus basé sur un langage composé de caractères, mais sur un langage composé de termes, où les termes sont des compositions closes d'opérateurs avec respect du type, ce que l'on appelle un langage terminologique typé. Et cela n'est qu'une première étape, car le langage terminologique fusse-t-il typé n'est qu'un langage algébrique, non-contextuel, qui est encore loin d'un langage contextuel en terme de capacité expressive. La construction UNIX et Linux des fichiers s'accordent finalement assez bien à notre construction en donnant les bases efficaces et propices à l'élaboration d'un traitement linguistique savant unificateur plus libre des données.

12) Caractères spéciaux

Le Bash utilise toute une panoplie de caractères au rôle spéciale que lon liste ici avec des exemples de leur utilisation :

 
#
Dièse
Commentaire

    #blabla
    echo Bonjour #blabla
S'il n'est pas en début de ligne, il faut un espace avant le dièse pour qu'il agisse comme début de commentaire. On entend par espace, des caractères blancs ou des tabulations.

;
Point-virgule
Séparateur d'instruction
    echo Bonjour; echo ici
;;
Double-point-virgule
Séparateur de cas
    case $x in
        ga)   echo "x=ga";;
        bu)   echo "x=bu";;
        zo)   echo "x=zo";;
    esac
.
Point
Répertoire courant
     ./a.sh
Execute le script a.sh se trouvant dans le répertoire courant.
    cp rep/fich .
Copie le fichier fich qui se trouve dans le sous-répertoire rep du répertoire courant, dans le répertoire courant.
.
Point
Composant d'un
nom de fichier
Le point sert aussi à indiqué les fichiers cachée. Ceux-ci commence par un point tel que le fichier .profil
Pour afficher les fichiers caché ls -a
..
Double-point
Répertoire parent
    cd ..
On se déplace dans le répertoire parent.
"
Guillemet
Chaine

Empêche l'interprétation de la plus part des caractères spéciaux présents dans la chaine.
echo "x  #;y"   produira   x  #;y
ec"ho" x"y  z"   produira   xy  z
Mais n'empêche pas l'interprétation du caractère $ et de l'antiquote
echo "$x"    produira le contenue de x
echo "`pwd`"
   produira    /home/dmabboux

'
Quote
Citation
Empêche l'interprétation de tous les caractères spéciaux présents dans la chaine.
echo '$x'    produira   $x
,
Virgule
Séparateur de paramètres
prog -k xxx,yyy,zzz
Le programme prog est lancé avec une option -k de paramètre xxx,yyy,zzz
\
Antislash
Echappement
Mécanisme d'échapement du caractère suivant.
\x ce comporte comme 'x' mais sans intéragire avec les autre cote '
echo a\b
 produira   ab
echo a\"b produira   a"b
echo a\$b
 produira   a$b
echo a\\b
 produira   a\b
/
Slash
Séparateur de chemin

/home/dmabboux/fich chemin absolu ou nom complet du fichier fich
ga/bu/zo chemin relatif ou nom incomplet du fichier zo. Le répertoire de départ et le répertoire courant.
./ga/bu/zo
commande pour executer le fichier zo à partir du répertoire courant.

`
Antiquote
Exécuteur d'instruction
Remplace l'instruction entre quotes inversés par son résultat.
echo aaa`echo x`bbb    produira   aaaxbbb
:
Deux-points
Commande nul

La commande NOP, ne fait rien et a comme état de sortie 0. Identique à true.

!
Point d'exclamation
Inverse l'état de sortie
! :    est identique à false. L'espace est nécessaire.
!=    est identique à ≠
*
Asrtérisque
Joker
Il sert de joker pour désigner plusieurs noms, il est remplacé par une chaine quelconque.
ls *plage*    liste les fichiers du répertoire courant qui contiennent plage dans leur nom.
?
Point d'interrogation
Opérateur de test

Indique un teste dans certaine expression.
Opératueur à trois arguments x?y:z. Exemple :
((a=14, b=(a<10)?1:2)) ; echo $b    retournera    2

$
Dollar
Contenu d'une variable

x=5aze    Cela rempli la variable x du contenu 5aze
echo $x    retournera    5aze

$?
Etat de sortie
echo $?   retourne l'état de sortie de la dernière commande shell executée dans ce terminal.
$$
PID
echo $$   retourne l'identifiant PID du processus
$0
Commande
echo $0  retourne la commande qui a lancer le processus
$1 $2
Premier argument
second argument

echo $1 retourne le premier argument. Les autres arguments sont désignés par :
$1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ...

n-ième argument
? ou utiliser shift. adressage indirect eval echo \$$x
n=2
eval echo \${$n}
retourne le n-ième argument.
$*
  echo $*  retourne tous les arguments
$#
  echo $#  retourne le nombre d'arguments   
${#x}
  echo ${#x}  retourne la taille de x (nombre de caractères quelque soit leur taille)  
$( )
eval
x=$(cat a.txt) récupère le contenue du fichier a.txt
x=$(< a.txt)
( )
Bloc de code
Bloc de code avec un sous-environnement
a=2 ; (a=4); echo $a   retournera   2
( )
Tableau
M=(ga bu zo) Initialise un tableau.
echo ${M[2]} retournera zo
echo ${M[*]} retournera ga bu zo
M[4]=titi modifit ou ajoute l'élément titi
echo ${#M[@]} retournera le nombre d'éléments 4
echo ${!M[@]} retournera la lise des clefs 0 1 2 4
unset M[4] suprime l'élément de clef 4
unset M suprime le tableau M
{ }
Expansion d'accolade
cat {a,b,c}>d Concatène les fichiers a,b,c et met le résulta dans le ficier d.
cp a.{txt,old} Compie le fichier a.txt dans le fichier a.old
{ }
Portion de code
f=/etc/fstab
{read l1; read l2} < $f    lit deux ligne du fichier /etc/fstab
[[ ]]
Test
 
(( ))
Virgule
Séparateur d'opérations arithmétiques
((a=3, t=15/a)) ; echo $a $t   retournera    3 5
Les opérations autorisées sont : + - * / % ** sur les entiers relatifs sur 8 octets
>
>&2
>>
<
<&2
<<
Redirection de fichier

prog > f     redirige la sortie stdout de prog dans le fichier f en l'effaçant.
prog >> f 
prog 1> f   redirige la sortie stdout de prog dans le fichier f en l'effaçant.
prog 2> f   redirige la sortie stderr de prog dans le fichier f en l'effaçant.

prog 2>&1 redirige la sortie stderr de prog sur la sortie stdout.

prog >&2 redirige la sortie stdout de prog vers la sortie stderr.

Descripteur    Device
       0              /dev/stdin
       1              /dev/stdout
       2              /dev/stderrtee

3<
4>
Descripteur de fichier
F=$(mktemp)    Crée un fichier temporaire et retourne son nom dans F
exec 3> "$F"     Crée le descripteur 3 d'écriture sur le fichier temporaire.
exec 4< "$F"     Crée le descripteur 4 de lecture sur le fichier temporaire.
rm -f "$F"         Supprime de force le fichier temporaire.  

echo "Bonjour" >&3 Envoi la chaine Bonjour sur la sortie n°3
cat <&4     Retourne Bonjour

3>&-
Fermeture
exec 3>&-   Ferme l'entrée de descripteur n°3
|
Tube
prog1 | prog2   redirige la sortie de prog1 vers l'entrée de prog2.
&
Esperluette
Job en arrière plan
prog &     Lance le programme en arrière plan (en fait un job).
<Ctl> z     Stop le processus en cours et le met en job en attente en arrière plan.
jobs           Liste les jobs, processus créés en arrière plan.
bg %2       Débloque le job en arrière plan n° 2
fg %2        Remet au premier plan le job n°2
kill %2      Tue le job n° 2
=
Egal
Opérateur d'affectation
x=toto21 met la chaine toto21 dans la variable x. Il ne doit pas y avoir d'espace autour du signe égale !
x=`cat a.txt` copie dans x le contenue du fichier a.txt
echo "$x" affiche le contenue de x
echo $x affiche le contenue de x en enlevant les sauts de ligne, les tabulations, les retours chariots et en réduisant chaque espace en un seul caractère blanc.
~
Tilde
Répertoire de l'utilisateur
cd ~ retourne sur le répertoire de l'utilisateur, identique à  :
cd $HOME
~+
Repertoire courant
cd ~+ retourne sur le répertoire courant, identique à  :
cd $PWD
~-
Repertoire courant
précédent
cd ~- retourne sur le répertoire courant, identique à  :
cd $OLDPWD

 

 

 

 

https://who23.github.io/2020/12/03/sockets-in-your-shell.html#fn:1

 

echo "coucouc" > /dev/tcp/localhost/80

 

exec 3>/dev/tcp/localhost/80

 

 

exec 3<>/dev/tcp/localhost/80

echo -e "GET / HTTP/1.1\n" >&3

cat <&3

--------------

apt install netcat ncat

nc -l p 4444 > r.txt &

                      nc 192.168.1.10 4444 < i.txt

 

 

nc -l -p 4444 | tee logfile.txt

Envoi de la sortie de nc dans un fichier et dans la fenêtre du terminal en même temps

 

nc -k -l -p 444 | tee logfile.txt

 

voir aussi ncat

ncat -4 -k -l -p 4455 | tee logfile.txt

echo Bonjour > /dev/tcp/192.168.1.10/4455

echo coucou > /dev/tcp/192.168.1.10/4455

sudo apt install shellcheck

 

ncat -4 -k -l -p 4455 -u | tee logfile.txt

echo Bonjour > /dev/udp/192.168.1.10/4455

-----------

ncat -4 -l -p 4455

exec 3<>/dev/tcp/192.168.1.10/4455

cat a.txt >&3

-----------

ncat -4 -l -u -p 4455

exec 3<>/dev/udp/192.168.1.10/4455

echo coucou >&3

cat a.txt >&3

 

exec 3<&-    #pour clore.

-----------

https://www.xmodulo.com/tcp-udp-socket-bash-shell.html

 

 

<< stop

l' entrée /dev/stdin jusqu'à rencontrer la ligne "stop" et alors il lira tous ce qui e a étét entré et executera la tâche

 

sans cela, c'est ^D qui fait office de stop.

---------

sl=echo -e "\n\r"

cat <<< Hello"$sl"Soleil

remplace l'entrée standart

 

cat < <(pwd; pwd)

x=$(cat a.txt)
x=`cat a.txt`

 

wc <(echo do; echo lilou)
2 2 9 /dev/fd/63

(echo foo;echo bar) | wc
2 2 9

---- 18 mars 2023 ----

 

echo Bonjour! > a.txt
od -tc a.txt

0000000 B o n j o u r ! \n
0000011

 

 

dd if=/dev/urandom count=1 bs=8 2>/dev/null | od -t x1 -A n

37 f9 ea 26 6c a1 bf 3a

 

https://linuxhandbook.com/create-virtual-block-device/

Les utilisateurs de Linux peuvent disposer d'un périphérique de bloc virtuel appelé "périphérique de boucle" qui mappe un fichier normal sur un bloc virtuel

je vais créer un fichier de 3 Giga octets :

dd if=/dev/zero of=VB.img bs=100M count=30

if=/dev/zero créera un bloc de 0 pour contenir les données.
of=VirtBlock.img est l'endroit où vous spécifierez le nom. Je suis allé avec VirtBlock.img.
bs=100M définira la taille d'un seul bloc.
count=30 créera des copies de blocs uniques pour des temps donnés. Cela signifie que 100 Mo * 30 fois correspondent à une taille d'environ 3 Go.

du -sh VB.img # vérifie la taille

sudo losetup -fP VB.img

-f nous trouvera des périphériques de boucle inutilisés et nous évitera des erreurs telles que "losetup : TO_BLOCK : échec de configuration du périphérique de boucle : périphérique ou ressource occupé".
-P forcera le noyau à analyser la table de partition sur le périphérique de boucle nouvellement créé.

sudo losetup -a affiche la liste les périfériques de boucle

/dev/loop0: [2066]:9000659 (/home/dmabboux/VB.img)

 

sudo mkfs.ext4 VB.img

mkdir VB

sudo mount -o loop /dev/loop0 VB

 

Vous pouvez maintenant vérifier le point de montage et la taille du périphérique de boucle récemment monté :

df -hP VB/

 

mount | grep VB

pour supprimer le périphérique boucle :

sudo umount /dev/loop0
sudo losetup -d /dev/loop0
sudo rm /dev/loop0

-----------------------------------

The lsblk command should give you the following output:

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
fd0 2:0 1 4K 0 disk
sda 8:0 0 2G 0 disk
└─sda1 8:1 0 1.4G 0 part /
sdb 8:16 0 3M 0 disk
└─sdb1 8:17 0 3M 0 part /scripts
sr0 11:0 1 1024M 0 rom

There are three different kinds of devices represented here, indicated by the first 2 characters in the device name:

fd - A floppy drive (Yeah, yeah... Comes with the VM. Just ignore it.)
sd - A hard disk (Originally SCSI, but now includes SATA, SAS, and others.)
sr - An optical drive

df -h

-------------------------------------------------------------------

fichier temporaire en mémoire vive :

mkdir /home/martin/ram
sudo mount -t tmpfs -o size=1000M none /home/martin/ram

Et pour le démonter :

sudo umount /home/martin/ram

Notez que la taille de ce fichier temporaire est limitée arbitrairement.

------------------------------------------------------------

Créer un tube nommé : (un tube synchrone)

mkfifo tubeB

ls -l B
prw-rw-r-- 1 dmabboux dmabboux 0 mars 21 11:32 tubeB

 

echo $x > tubeB (bloque si pas lu)
read x < tubeB (bloque si pas de message dans le tube)

 

 

echo $RANDOM $RANDOM $RANDOM $RANDOM
3466 6521 4426 9349

 

Le programme echo à deux options :

-n : N'affiche pas de saut de ligne final.
-e : Permet l'interprétation des échappements.

Le caractère d'échappement est \ lorsqu'il est dans une chaine délimité. L'option -e de la commande echo permet d'interprété les caractères spéciaux placé dans une chaine délimitée :

\b : Retourne en arrière d'un caractère.
\c : Ne produit rien après.
\n : Saut de ligne.
\r : Retour chariot sans saut de ligne.
\t : Tabulation horizontale.
\v : Tabulation verticale.
\xHH : Caractère de code héxadécimal sur 2 chiffres HH.

Pour ajouter un caractère saut de ligne dans la chaine produite par le programme echo, spécifiez l'option -e, et insérer "\n" ou '\n' ou simplement \n si l'expression est déjà dans une chaine délimité. Par exemple :

echo -e "xxx\nyyy"

Cela produira :

xxx
yyy

L'option -e de la commande echo permet d'interprété les caractères spéciaux tel que le saut de ligne \n, la tabulation \t ou la tabulation verticale \v dans une chaine délimité. Sans cette option la chaine délimité est retournée (toujours sans ses délimitations) :

xxx\nyyy

Le caractère d'échappement \ en dehors des chaînes délimités joue un rôle particulier. Il neutralise l'éventuel rôle spécial du caractère suivant et se retire du résultat. Par exemples les saisies suivantes suivie de la touche entrée auront comme résultat :

echo xx\yy  produira aayy                                                   
echo xx\\yy  produira aa\yy  
echo "x\\y"  produira x\\y  
echo x\"y  produira x"y  
echo x\"y"z\z"  produira x"yz\z  
echo \
 
 attendra une saisie complémentaire à la ligne suivante,
   et l'échappement ne neutralisera que le caractère saut de ligne.

---- 15 mars 2023 ----

On veut proposer une syntaxe beaucoup plus pratique et riche, et finalement moins arbitraire. Comme nous avons besoin de bâtir sur des fondations existantes, nous n'allons pas modifier celle-ci mais simplement les adapter par simple perfectionnement syntaxique des données transportée. Les tubes ne transporteront plus de simples caractères ou de simples mots, mais des termes. Les données ne seront plus basé sur un langage composé de caractères, mais sur un langage composé de termes, où les termes sont des compositions closes d'opérateurs avec respect du type, ce que l'on appelle un langage terminologique typé. Et cela n'est qu'une première étape, car le langage terminologique fusse-t-il typé n'est qu'un langage algébrique, non-contextuel, qui est encore loin d'un langage contextuel en terme de capacité expressive. La construction UNIX et Linux des fichiers s'accordent finalement assez bien à notre construction en donnant les bases efficaces et propices à l'élaboration d'un traitement linguistique savant unificateur plus libre des données.

Le mécanisme qui met en oeuvre cette possibilité est l'utilisation d'une variable global PATH qui indique au système où chercher les programmes qui peuvent ainsi être évoqué par leur seul nom.

 

Précédent
 
Suivant

 


Dominique Mabboux-Stromberg