2016-05-31 13 views
1

habe ich eine Datei mit dem Namen Descriptor wie dieeine benannte Dateideskriptors Closing

exec {gui_outfd}<>$gui_outpipe 

jetzt will ich es schließen:

exec {gui_outfd}>&- 

Dies ergibt

./game.sh: line 338: read: 14: invalid file descriptor: Bad file descriptor 

Was soll ich tun falsch?

EDIT Linien 330-357 in meinem Skript:

run_gui & gui_pid=$! 
run_ai1 & ai1_pid=$! 
exec {gui_outfd}>&- 
while true; do 
    echo "Started the loop" 
    while true; do 
     eval $(isalive2 $gui_pid $ai1_pid) 
     read -u $ai1_outfd line || echo "Nothing read" 
     if [[ $line ]]; then # line 338 
      echo "Piping to GUI $line" 
      echo "$line" >&$gui_infd 
      if [[ "$line" == "END_TURN" ]]; then 
       break 
      fi 
     fi 
    done 
    echo TURNCHANGED 
    while true; do 
     read -u $gui_outfd line || echo "nothing read" 
     if [[ $line ]]; then 
      echo "Piping to AI $line" 
      echo "$line" >&$ai1_infd 
      if [[ "$line" == "END_TURN" ]]; then 
       break 
      fi 
     fi 
    done 
done 

Und die aufgerufenen Funktionen:

run_gui() 
{ 
    exec "$GAME_BIN" $args <&$gui_infd >&$gui_outfd 
} 

run_ai1() 
{ 
    exec "$ai1" <&$ai1_infd >&$ai1_outfd 
} 
+2

Es sieht eher so aus, als ob ein Prozess versucht, aus dem Deskriptor zu lesen, nachdem Sie es geschlossen haben, anstatt ein Problem mit dem Schließen selbst zu sein. – chepner

+0

@chepner \t Ja, aber der Dateideskriptor sollte noch offen sein durch den 'run_gui'-Subprozess, da es eine Subshell ist ... Siehe das aktualisierte OP – marmistrz

+0

Allerdings denke ich, @chepner ist sehr wahrscheinlich richtig: nur weil die FD in Frage ist immer noch offen in der "$ GAME_BIN" -Prozess bedeutet nicht, dass es immer noch in der Shell geöffnet ist, die versucht, davon zu lesen. –

Antwort

3

Die Kombination von ...

exec {gui_outfd}>&- 

... gefolgt ohne weitere Umleitungen oder Änderungen von $gui_outfd von ...

read -u $gui_outfd line || echo "nothing read" 

... zum Scheitern verurteilt ist genau zum Scheitern verurteilt, wie Sie es tut beschreiben.

Sobald ein Prozess einen Dateideskriptor schließt, kann der Prozess diesen FD danach nicht mehr verwenden, außer nach dem Verknüpfen mit einer neuen offenen Dateibeschreibung. Das hat nichts mit irgendwelchen anderen Prozessen zu tun, die die gleiche Datei geöffnet haben, oder mit den Beziehungen dieser Prozesse zu denen, die ihre FD geschlossen haben.

Schließen Sie die FD nicht, bis Sie damit fertig sind.

+0

Aber ich schließe es nur zum Schreiben, nicht zum Lesen. Ich möchte es lesen können, aber ich möchte eine defekte Pipe, wenn der GUI-Prozess beendet wird. Wie kann ich es erreichen? – marmistrz

+1

@marmistrz, du hast ein Missverständnis. Eine Datei ist entweder geöffnet oder geschlossen. Wenn es geöffnet ist, kann es sein, dass es nur Lesen oder nur Schreiben erlaubt oder beides, aber Sie können es nicht halb schließen. Es gibt keinen funktionalen Unterschied zwischen '{gui_outfd}> & -' und '{gui_outfd} <& -'. Wenn Sie eine Pipe zwischen zwei Prozessen haben wollen, sollten Sie vielleicht den eingebauten Pipe-Operator der Shell, '|', berücksichtigen. –