2014-09-17 8 views
8

Ich habe zwei Bash-Skript. Ein Skript in einem FIFO schreiben. Der zweite liest aus dem FIFO, aber NACH dem ersten Ende zu schreiben.Schreiben und lesen von einem Fifo aus zwei verschiedenen Skript

Aber etwas funktioniert nicht. Ich verstehe nicht, wo das Problem liegt. Hier der Code.

Das erste Skript ist (der Autor):

#!/bin/bash 

fifo_name="myfifo"; 

# Se non esiste, crea la fifo; 
[ -p $fifo_name ] || mkfifo $fifo_name; 

exec 3<> $fifo_name; 

echo "foo" > $fifo_name; 
echo "bar" > $fifo_name; 

Das zweite Skript ist (der Leser):

#!/bin/bash 

fifo_name="myfifo"; 

while true 
do 
    if read line <$fifo_name; then 
     # if [[ "$line" == 'ar' ]]; then 
     # break 
     #fi 
     echo $line 
    fi 
done 

jemand mir bitte helfen? Danke

+1

Was tun Du meinst mit "Etwas funktioniert nicht"? – choroba

+0

Kein Skript gibt mir einen Fehler. Aber wenn ich das zweite Skript ausführe, wird nichts auf dem Bildschirm gedruckt. Also ich verstehe nicht, wenn ich falsch liege, wenn ich in der FIFO schreibe oder wenn ich aus dem FIFO – Ciccio

Antwort

6

das zweite Skript Ersetzen durch:

#!/bin/bash  
fifo_name="myfifo" 
while true 
do 
    if read line; then 
     echo $line 
    fi 
done <"$fifo_name" 

Dieses nur einmal die Fifo öffnet und liest von ihm jede Zeile.

+0

lesen Doe nicht zu mir arbeiten :(Wenn ich das zweite Skript ausführen nichts passiert und auch das Skript nicht beendet :(Ich muss drücken STRG + C – Ciccio

+0

@Ciccio Ja, das Skript wird nicht beendet, da es darauf wartet, dass etwas vom Fifo gelesen wird.Während es wartet, führen Sie das andere Skript aus, das in den Fifo schreibt. – John1024

+0

@Ciccio Auch das erste Skript wird nicht beendet, bis ein Prozess vom Fifo gelesen hat. Wenn das zweite Skript fertig gelesen hat, was das erste Skript geschrieben hat, wird das erste Skript beendet. Das zweite Skript wartet wegen der while-true-Schleife weiterhin auf weitere Eingaben. – John1024

2

Das Problem mit Ihrer Einrichtung ist, dass Sie die Fifo-Erstellung im falschen Skript haben, wenn Sie den Fifo-Zugriff auf die Zeit steuern möchten, wenn der Reader tatsächlich ausgeführt wird. Um das Problem zu beheben, müssen Sie so etwas wie dies tun:

Leser: fifo_write.sh

#!/bin/bash 

fifo_name="/tmp/myfifo" 

# Se non esiste, exit :); 
[ -p "$fifo_name" ] || { 
    printf "\n Error fifo '%s' not found.\n\n" "$fifo_name" 
    exit 1 
} 

[ -n "$1" ] && 
    printf "%s\n" "$1" > "$fifo_name" || 
    printf "pid: '%s' writing to fifo\n" "$$" > "$fifo_name" 

exit 0 

Betrieb:

#!/bin/bash 

fifo_name="/tmp/myfifo"       # fifo name 

trap "rm -f $fifo_name" EXIT     # set trap to rm fifo_name at exit 

[ -p "$fifo_name" ] || mkfifo "$fifo_name"  # if fifo not found, create 

exec 3< $fifo_name        # redirect fifo_name to fd 3 
               # (not required, but makes read clearer) 
while :; do 
    if read -r -u 3 line; then     # read line from fifo_name 
     if [ "$line" = 'quit' ]; then   # if line is quit, quit 
      printf "%s: 'quit' command received\n" "$fifo_name" 
      break 
     fi 
     printf "%s: %s\n" "$fifo_name" "$line" # print line read 
    fi 
done 

exec 3<&-          # reset fd 3 redirection 

exit 0 

Schriftsteller fifo_read.sh: (Startleser im 1. Terminal)

$ ./fifo_read.sh       # you can background with & at end 

(Start Schriftsteller in zweitem Anschluss)

$ ./fifo_write.sh "message from writer" # second terminal 
$ ./fifo_write.sh 
$ ./fifo_write.sh quit 

Ausgang in ersten Terminal:

$ ./fifo_read.sh 
/tmp/myfifo: message from writer 
/tmp/myfifo: pid: '28698' writing to fifo 
/tmp/myfifo: 'quit' command received 
+0

+1 Sie adressieren das Problem zur Hand, aber als eine Anmerkung: Wäre nicht 'read -r line <$ fifo_name' sein besser? Wie es jetzt ist, wird das * reader * -Skript nach der ersten Nachricht in eine CPU-intensive Schleife eintreten. Dasselbe gilt für den Ansatz [von John1024] (http://stackoverflow.com/a/25901141/1968548). – Runium

+0

Danke. Wie im Kommentar erwähnt, ist die ständige Umleitung zu fd3 nicht notwendig, der Zweck war lediglich, die Skriptlogik sauber zu halten, um zu verdeutlichen, dass der FIFO umgeleitet wurde und zum Lesen verwendet wurde. (Es hat auch die Möglichkeit gegeben, das Lesen von einem benutzerdefinierten Dateideskriptor zu zeigen - was notwendig ist, wenn man von mehreren fds in einer einzelnen Schleife liest (zB fd3 & stdin). Ich sehe keinen Grund, warum dein Ansatz nicht genauso gut funktionieren würde ohne Hand. Geben Sie es eine Chance. –

0

Das folgende Skript den Job tun soll:

#!/bin/bash 

FIFO="/tmp/fifo" 

if [ ! -e "$FIFO" ]; then 
     mkfifo "$FIFO" 
fi 

for script in "[email protected]"; do 
     echo $script > $FIFO & 
done 

while read script; do 
     /bin/bash -c $script 
done < $FIFO 

Gegeben zwei Skript a.sh und b.sh wo passieren "a" und "b" stdout beide Skripte bzw. wird man das folgende Ergebnis (vorausgesetzt, dass das Skript oben genannt test.sh) erhalten:

./test.sh /tmp/a.sh /tmp/b.sh 
a 
b 

Best, Julian

Verwandte Themen