Wie kann verhindert werden, dass der Beendigungsbefehl EOF an Named Pipes sendet?

3890
justhalf

Das Problem, mit dem ich konfrontiert war, ist genau dieses: http://www.linuxmisc.com/4-linux/d7863c256bccbfb6.htm

Ich möchte in der Lage sein, ein Programm auszuführen, das stdin verwendet, und Daten zu schreiben, wann immer ich Lust habe. Ich kann das mit FIFOs namens Pipes tun. z.B:

txtplay < named_pipe.fifo

echo "Hello World" > named_pipe.fifo

Dies hat jedoch den Nachteil, dass der erste Befehl nach dem Ende des zweiten Befehls beendet wird. Was ich will ist das gleiche wie:

txtplay

In der Tat, ich kann meine Daten einfach immer einfügen, wenn ich möchte, und muss mir keine Sorgen darüber machen, dass das Dateiende zu sehen ist. Leider kann ich dies nicht einfach tun, da ich möchte, dass die Daten an sie gesendet werden, bevor sie vom Programm erkannt werden.

Warum lade ich das Programm nicht jedes Mal, wenn ich Daten senden möchte? Zu langsam.

Was ich im Grunde möchte, ist eine Möglichkeit, die Ausgabe eines gegebenen Befehls an eine FIFO-Pipe ohne das Dateiende umzuleiten. Wie funktioniert das EOF-Geschäft, wenn ich gerade dabei bin? Gibt es einen speziellen "EOF" -Befehl, oder wenn keine Daten mehr empfangen werden oder wenn das ursprüngliche Programm, das die Daten ausgibt, beendet ist?

Gibt es dafür eine Lösung?

3
Echo sendet kein EOF, es sendet eine neue Leitung. Sie können die neue Zeile mit der Option -n unterdrücken. Ich denke, die EOF, die Sie sehen, ist die EOF der von Ihnen erstellten Datei. Es besteht eine gute Chance, dass ich Ihr Problem missverstehe, daher ist dies nur ein Kommentar. bjanssen vor 9 Jahren 0
Die EOF wird erstellt, wenn das `echo` beendet ist, wie von @Luno gezeigt. justhalf vor 9 Jahren 1

2 Antworten auf die Frage

4
Luno

Führen Sie alle Ihre Befehle in einer Sub-Shell (oder in Bash in Klammern) aus und leiten Sie die Sub-Shell an die benannte Pipe weiter.

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

Um die EOF-Frage zu beantworten, wird EOF geschrieben, wenn das Dateihandle geschlossen wird. Wenn Sie von einem Programm aus umleiten, erhalten Sie EOF, wenn dieses Programm (in diesem Fall Echo) beendet wird. Durch das Einkapseln mehrerer Befehle in Klammern erhalten Sie nur eine EOF, wenn die schließende Klammer erreicht wird.

Vielen Dank für Ihre Antwort. Ich habe heute Morgen darüber nachgedacht, aber damals konnte ich es nicht auf meinen Anwendungsfall anwenden. Nach einigen weiteren Überlegungen ist es tatsächlich möglich. Vielen Dank :) justhalf vor 9 Jahren 0
1
Pod

Wenn Sie einen Griff für die Pipe offen halten, wird er nicht durch jeden Echo-Befehl geschlossen.

#!/usr/bin/env bash fifo_with_exec() { echo "fifo_with_exec"  readonly TMP_PIPE=$(mktemp -u) mkfifo -m 600 $ echo "pipe created: $"  # Here is the important bit exec 9<> $  zenity --progress --no-cancel < $ & zenity_pid=$! echo "zenity_pid: $"  echo "0" > $ echo "#Run command A" > $ echo "output of command A" sleep 2 echo "40" > $  echo "#Run command B" > $ echo "output of command B" sleep 2 echo "80" > $  echo "#Run command C" > $ echo "output of command C" sleep 0.5 echo "100" > $ } fifo_with_exec 

Wenn Sie diese exec-Anweisung entfernen, werden Sie feststellen, dass die Funktion beim zweiten Echo hängt, da Zenity stoppt, wenn EOF vom ersten Echo erkannt wird.