5 votes

Comment empêcher une commande de terminaison d'envoyer un EOF aux tubes nommés ?

Le problème auquel j'ai été confronté est exactement celui-ci : http://www.linuxmisc.com/4-linux/d7863c256bccbfb6.htm

Je veux pouvoir exécuter un programme qui prend stdin et écrit des données. quand j'en ai envie. Je peux le faire avec des pipes nommés fifo. par exemple :

txtplay < named_pipe.fifo

echo "Hello World" > named_pipe.fifo

Toutefois, cette méthode présente l'inconvénient de faire sortir la première commande de l'application après la fin de la seconde. Ce que je veux, c'est la même chose que :

txtplay

Je peux donc introduire mes données quand je le souhaite, sans m'inquiéter de ce qui se passe dans mon pays. de la fin du fichier. Malheureusement, je ne peux pas simplement faire cela, car je car je veux que les données qui lui sont envoyées soient traitées par un filtre avant que le programme ne les voie. avant que le programme ne les voie.

Pourquoi ne pas simplement charger le fichier données ? C'est trop lent.

Ce que je veux, en fait, c'est un moyen de rediriger la sortie d'un fichier vers un fifo nommé pipe, sans la fin du fichier. Pendant que j'y suis comment fonctionne cette histoire de fin de fichier ? Existe-t-il une commande spéciale "EOF", ou est-ce que c'est lorsque plus aucune donnée n'est reçue, ou lorsque le programme d'origine produisant les les données se termine ?

Existe-t-il une solution à ce problème ?

6voto

Luno Points 161

Exécutez toutes vos commandes dans un sous-shellShell (ou dans bash, entre parenthèses), et redirigez le sous-shell vers le tuyau nommé.

( 
     # some stuff
     echo "foo"
     # some other stuff
     echo "bar"
     # end of my commands
) > /home/foo/bar/named_pipe

Et pour répondre à la question EOF, EOF est écrit lorsque la poignée du fichier se ferme. Si vous redirigez à partir d'un programme, vous obtenez EOF lorsque ce programme (echo, dans ce cas) se termine. En encapsulant plusieurs commandes dans des parenthèses, vous n'obtenez qu'un seul EOF lorsque la parenthèse fermée est atteinte.

4voto

Marky Points 1501

Si vous gardez une poignée ouverte sur le tuyau, elle ne sera pas fermée par chaque commande echo.

#!/usr/bin/env bash
fifo_with_exec() {
    echo "fifo_with_exec"

    readonly TMP_PIPE=$(mktemp -u)
    mkfifo -m 600 ${TMP_PIPE}
    echo "pipe created:  ${TMP_PIPE}"

    # Here is the important bit
    exec 9<> ${TMP_PIPE}

    zenity --progress --no-cancel < ${TMP_PIPE} &
    zenity_pid=$!
    echo "zenity_pid: ${zenity_pid}"

    echo "0" > ${TMP_PIPE}
    echo "#Run command A" > ${TMP_PIPE}
    echo "output of command A"
    sleep 2
    echo "40"  > ${TMP_PIPE}

    echo "#Run command B" > ${TMP_PIPE}
    echo "output of command B"
    sleep 2
    echo "80" > ${TMP_PIPE}

    echo "#Run command C" > ${TMP_PIPE}
    echo "output of command C"
    sleep 0.5
    echo "100" > ${TMP_PIPE}
}
fifo_with_exec

Si vous supprimez l'instruction exec, vous remarquerez que la fonction se bloque sur le deuxième écho, car Zenity s'arrête lorsqu'il voit EOF dans le premier écho.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X