• # Mais pourquoi est-il aussi méchant ?

    Posté par . En réponse au message zenity : processus père/fils, fifo,.... Évalué à 5.

    J'ai compris que c'est parce que $var est déclaré dans un processus fils et qu'il ne peut donc pas passé de variable au processus père.

    En effet.

    [...] il est possible d'utiliser fifo mais je ne comprends vraiment pas comment ca s'utilise. Chaque essai que j'ai fait s'est soldé par un échec (script qui reste en attente)

    D'abord, ici, fifo n'est qu'un nom de fichier; un fichier particulier : c'est un pipe nommé (pipe==fifo). En gros, c'est un tuyau. Un processus écrit d'un côté du tuyau, et un autre lit de l'autre côté. C'est à sens-unique.

    Le problème des pipes, c'est qu'il ont une taille fixe, 4KiB IIRC. Le processus qui écrit est bloqué dès que le pipe est rempli, ce qui peut arriver si personne ne lit à l'autre bout, ou si l'autre bout ne se vide pas assez vite. Dès que le lecteur lit un bout du pipe, l'écrivain peut alors recommencer à le remplir. Ainsi de suite.

    L'exemple que tu pointes (mal, ceci dit, il faut lire tout les commentaires pour voir à quoi tu fais référence) est bancal. Reprenons-le :

    #!/bin/sh
    mkfifo fifo
    cat $fichier | grep $valeur_recherche > fifo
    while read ligne; do
     (( var = var + 1 ))
     echo $var
    done < fifo
    echo $var
    rm fifo
    

    Si le contenu filtré :

    cat $fichier | grep $valeur_recherche > fifo
    

    dépasse les 4KiB, alors ca va bloquer en attendant que le pipe se libère, ce qui n'arrivera jamais avec ce script, puisque la lecture se fait après :

    while read ligne; do
     (( var = var + 1 ))
     echo $var
    done < fifo # <--- ici on lit depuis le pipe
    

    Donc, il faut mettre l'écrivain en arrière plan, pour qu'il puisse continuer à écrire.

    En plus, il y a une erreur de syntaxe sur cette ligne :

     (( var = var + 1 )) # On devrait écrcire : var=$(( var + 1 ))
    
    #!/bin/sh
    rm -f fifo # Suppression de la fifo au cas ou...
    mkfifo fifo # Création de la fifo
    # Lancement de l'écrivain', en arrière plan, pour qu'il ne bloque
    # pas sur remplissage de la fifo : note le '&' en fin de ligne
    cat "${fichier}" | grep "${valeur_recherche}" > fifo &
    # Lancement du 'lecteur'
    while read ligne; do
    var=$(( var + 1 ))
     printf "%s"\n" "${var}"
    done < fifo
    # Resultat :
    printf "J'ai lu '%s' lignes\n" "${var}"
    # Plus besoin de la fifo, on la supprime
    rm -f fifo
    

    MAIS ! Cela ne fonctionne plus si la sortie de la boucle est à son tour 'pipée' dans une commande :

    while read ligne; do
    var=$(( var + 1 ))
     printf "%s"\n" "${var}"
    done < fifo |zenity
    

    Là, je sèche... :-/