Debian Debian-France Debian-Facile Debian-fr.org Debian-fr.xyz Debian ? Communautés

Debian-facile

Bienvenue sur Debian-Facile, site d'aide pour les nouveaux utilisateurs de Debian.

Vous n'êtes pas identifié(e).

#1 02-04-2022 15:50:05

petipatapon
Membre
Distrib. : Debian bulleye 11
Noyau : Linux 5.10.0-9-amd64
(G)UI : xfce
Inscription : 05-02-2022

[RÉSOLU] Tube nommé (FIFO) bloquant

Bonjour,
j'essaye de crée un préprocesseur qui prendrait en entrée un script shell pour afficher en sortie à la fois les lignes du script suivies immédiatement de leur propre sortie.
Ainsi, pour le script suivant :

echo "ceci est un script bash"
cd /home
pwd


il renverrait le fichier texte suivant :

$ echo "ceci est un script bash"
ceci est un script bash
$ cd /home
$ pwd
/home

Le résultat est bien sûr proche de ce qu'on obtiendrait si on copiait-collait le texte du terminal après exécution du script.
Mon intention est d'ailleurs de reproduire ce comportement afin d'automatiser la copie de texte depuis le terminal.

J'ai tenté de réaliser mon idée avec bash en utilisant des tubes nommés (FIFO) grâce au script que voilà :


#!/bin/sh

bash <fifo_entree >fifo_sortie &
while read LIGNE ; do
  # On récupère une ligne de script dans l'entrée standard
  # On la réécrit dans la sortie standard avec un commentaire
  echo "# [commentaire décrivant la fonction de la commande]"
  echo "\$ $LIGNE"
  # On envoie la nouvelle ligne de commande à notre instance de bash
  echo "$LIGNE" > fifo_entree
  # On récupère la sortie de l'instance de bash
  cat fifo_sortie
done

Hélas, le script se bloque après avoir lu la première ligne de l'entrée standard.
Il parvient cependant à exécuter la première ligne de script en entrée standard et à en rediriger la sortie vers le terminal, mais bloque immédiatement après.
Je me doute que ce comportement est lié au fonctionnement des tubes nommés, mais je n'arrive pas à mettre le doigt sur le défaut du script.
Quelqu'un a-t-il une idée ?

Dernière modification par petipatapon (08-04-2022 19:01:58)

Hors ligne

#2 02-04-2022 16:19:48

Croutons
Membre
Distrib. : Debian10 Buster
Noyau : Linux 4.19.0-18-amd64
(G)UI : Mate
Inscription : 16-12-2016

Re : [RÉSOLU] Tube nommé (FIFO) bloquant

Hello
j'ai pas compris l'idée du script, il doit faire quoi exactement?
faut dire je connais pas grand chose non plus , je bidouille quelque script simple , mais la j’ai même pas compris le début

-->les cahiers du debutant<--      WikiDF-->Découvrir les principales commandes Linux<--
L' expérience, c'est le nom que chacun donne à ses erreurs. Oscar Wilde

Hors ligne

#3 02-04-2022 18:35:03

hybridemoineau
Membre
Inscription : 21-02-2016

Re : [RÉSOLU] Tube nommé (FIFO) bloquant

Ce que tu cherches à faire, si je comprends bien, peut être obtenu automatiquement avec l'option -x à bash (bash -x script).

Hors ligne

#4 07-04-2022 19:50:14

petipatapon
Membre
Distrib. : Debian bulleye 11
Noyau : Linux 5.10.0-9-amd64
(G)UI : xfce
Inscription : 05-02-2022

Re : [RÉSOLU] Tube nommé (FIFO) bloquant

Ce que tu cherches à faire, si je comprends bien, peut être obtenu automatiquement avec l'option -x à bash (bash -x script).

C'est exactement ce que je voulais faire, merci !
Pour revenir au script, il y a une solution élémentaire qui marcherait pour bash - sans lancer de shell en arrière plan - que voilà :

#!/bin/sh
while read LIGNE ; do
  echo "$ $LIGNE"
  $LIGNE
done

Mais mieux vaut utiliser l'option -x car ce script ne peut gérer que les syntaxes qui tiennent sur une seule ligne.

Hors ligne

#5 07-04-2022 21:02:48

Tawal
Membre
Distrib. : Debian Stable à jour
Noyau : amd64
(G)UI : Xfce
Inscription : 25-02-2021

Re : [RÉSOLU] Tube nommé (FIFO) bloquant

Hello,

Tu peux aussi ajouter l'option "-v" à bash pour avoir plus de "verbosité".

Sinon, pour expliquer pourquoi ton script du #1 "bloque", cela vient du cat fifo_sortie et du type de fichier lu (fifo en l'occurrence).
En effet, cat attend un EOF (End Of File = caractère spécial) pour terminer sa lecture.
Tant qu'il ne rencontre pas le caractère de fin de fichier, cat attend la suite ... éternellement.
Et un fifo n'obtient pas de caractère EOF tant qu'il est ouvert. C'est d'ailleurs un peu son principe ...

Edit : Illustration

$ mkfifo fifo_file
$ exec 6<>fifo_file 4>fifo_file 5<fifo_file 6>&-
$ echo "test" >&4
$ cat <&5
test
^C
$

obligé de faire CTRL+C pour arrêter cat.

Edit : Pour vraiment illustrer

$ echo "test de fin" >&4
$ exec 4>&-
$ cat <&5
test de fin
$

Dernière modification par Tawal (07-04-2022 21:20:32)


Comme la science n'est pas infuse, elle se diffuse.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

En ligne

#6 08-04-2022 18:59:52

petipatapon
Membre
Distrib. : Debian bulleye 11
Noyau : Linux 5.10.0-9-amd64
(G)UI : xfce
Inscription : 05-02-2022

Re : [RÉSOLU] Tube nommé (FIFO) bloquant

Merci pour tes explications,
Si je comprends bien, dans le premier exemple, cat ne se termine pas car fifo_file est toujours ouvert par bash sous le descripteur de fichier 4.
Alors que dans le second exemple, il est fermé grâce à la ligne exec 4>&-. Par conséquent le noyau écrit EOF et cat peut se terminer lorsqu'il rencontre le caractère EOF.

Deux questions me taraudent cependant :
1) Pourquoi echo entre-t-il dans un état bloquant lorsqu'il écrit dans un tube FIFO. Par exemple :

$ echo "test" > fifo
état bloquant
^C
$

Ici, echo se bloque. Or echo se contente d'écrire dans un fichier, il n'attend pas de trouver le caractère EOF. Il devrait simplement écrire son texte dan le tube FIFO et se terminer, non ? Et pourquoi se débloque-t-il lorsqu'on cat le contenu du tube depuis un autre terminal.

2) Dans ton exemple, echo n'est pas bloquant, alors qu'il réalise exactement la mếme opération d'écriture dans le tube que dans l'exemple précédent. Je me doute que ce comportement résulte de la redirection $ exec 6<>fifo_file 4>fifo_file 5<fifo_file 6>&-. En particulier de 6<>fifo_file dont j'ignore la fonction. Que fait-elle ? Et pourquoi echo n'est-il pas bloquant quand on l'utilise ?

Dernière modification par petipatapon (08-04-2022 19:00:40)

Hors ligne

#7 08-04-2022 21:07:36

Tawal
Membre
Distrib. : Debian Stable à jour
Noyau : amd64
(G)UI : Xfce
Inscription : 25-02-2021

Re : [RÉSOLU] Tube nommé (FIFO) bloquant

En fait, la commande :

exec 6<>fifo_file 4>fifo_file 5<fifo_file 6>&-


fait ceci :
    - 6<>fifo_file  : ouvre en écriture et lecture le descripteur fd6 vers fifo_file.
    - 4>fifo_file    : ouvre en écriture le descripteur fd4 vers fifo_file.
    - 5<fifo_file    : ouvre en lecture le descripteur fd5 vers fifo_file.
    - 6>&-           : ferme le fd6.

En fait, un tube nommé a besoin d'être ouvert en écriture ET en lecture pour être "non-bloquant" (6<>fifo_file).
Ensuite on peut écrire et lire "à volonté", mais autant définir un descripteur pour chaque flux (4>fifo_file et 5<fifo_file).
Puis, le fd 6 devient inutile, autant le fermer (6>&-). Et puis, c'est pas très bon à l'usage un descripteur ouvert dans les 2 sens.

J'espère avoir été assez clair smile

Edit:
Tu peux aussi ouvrir un fifo ainsi:

mkfifo fifo_file
echo -n >fifo_file & exec 5<fifo_file
exec 4>fifo_file


echo est "bloquant" mais est mis en arrière plan et ouvre en écriture le fifo, puis on ouvre en lecture le fifo (exec 5<fifo_file)
Là, on peut tranquillement définir un fd pour l'écriture (sans être "bloquant").

Edit2:
On pourrait faire une analogie avec le web.
Tu envoies une donnée que si tu es sûr d'avoir un aboutissant, le tube c'est pareil, le shell attend qu'il y ait une entrée et une sortie.

Dernière modification par Tawal (08-04-2022 21:32:00)


Comme la science n'est pas infuse, elle se diffuse.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

En ligne

#8 09-04-2022 11:41:30

petipatapon
Membre
Distrib. : Debian bulleye 11
Noyau : Linux 5.10.0-9-amd64
(G)UI : xfce
Inscription : 05-02-2022

Re : [RÉSOLU] Tube nommé (FIFO) bloquant

D'accord, j'ai compris !
Et je suppose qu'on ne peut pas écrire sans bloquer :

exec 4>fifo_file 5<fifo_file

parce que les redirections sont faites de façon successive, de sorte que le tube soit bloquant après 4>fifo_file et n'exécute jamais 5<fifo_file. Il n'est donc ouvert qu'en écriture et bloque.
C'est pourquoi on doit l'ouvrir temporairement en lecture et en écriture avec le descripteur six, juste le temps d'effectuer les autres redirections. Puis, on peut fermer le descripteur 6 sans bloquer le tube vu qu'il est ouvert en lecture par le descripteur 5 et en écriture par 4.

Hors ligne

#9 09-04-2022 17:16:59

Tawal
Membre
Distrib. : Debian Stable à jour
Noyau : amd64
(G)UI : Xfce
Inscription : 25-02-2021

Re : [RÉSOLU] Tube nommé (FIFO) bloquant

Exact yes.gif
Tu as déjà une meilleure approche que tu n'avais en ouvrant ce fil wink

Comme la science n'est pas infuse, elle se diffuse.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

En ligne

#10 07-07-2022 17:07:24

petipatapon
Membre
Distrib. : Debian bulleye 11
Noyau : Linux 5.10.0-9-amd64
(G)UI : xfce
Inscription : 05-02-2022

Re : [RÉSOLU] Tube nommé (FIFO) bloquant

Bonjour,
cette discussion commence à dater, mais je voulais simplement ajouter que j'ai trouvé une commande pour réaliser ce que je voulais faire initialement, à savoir : récupérer tout le contenu affiché par le terminal au cours d'une session (les commandes tapées par l'utilisateur plus leur sortie) grâce à la commande script.
La commande script -a démarre un nouveau shell. Tout le texte affiché sur terminal pendant la durée de la session est enregistré dans un fichier appelé par défaut typescript dans le répertoire courant (y compris les séquences d'échappement ANSI). C'est très pratique en combinaison avec de utilitaires comme xclip ou xsel, notamment pour copier des logs d'erreur sur le site Debian facile tongue

Hors ligne

Pied de page des forums