2016-06-26 6 views
1

update: Ich denke, der folgende Code könnte in die falsche Richtung gehen - aber die Frage bleibt, kann ich öffnen eine Pipe, um alle Ausgaben zu protokollieren (Datei & Konsole), dieses Protokoll anzuhalten und in ein neues Protokoll zu loggen (neue Datei & Konsole) und dann erneut an die FD für den ursprünglichen Logger anzuhängen, indem FDs herumgedreht und nicht wieder geöffnet werden die ursprüngliche ProtokolldateiVerwenden Sie 'exec', um alle Ausgaben zu protokollieren, zu stoppen und dann wieder an die gleichen FDs/Named Pipes anzuschließen.

Versuchen, mein Wissen über FDs in bash zu verbessern. Ich versuche, alle Ausgaben der Haupt "Meta" test.sh zu protokollieren - aber in eine andere Datei loggen, wenn ich zu "Sektionen" komme - z. Funktionen, Quelltexte, etc. Und dann zurück zum Anhängen an das "Meta" -Log.

Ich weiß, ich könnte das ganz einfach mit Subshells erreichen - oder indem ich das 'meta' Log wieder öffne und von dort anfüge, aber kann irgendjemand helfen, dies zu erreichen, indem ich FDs umschalte?

-bash-4.2# ./test.sh 
SECTION: stdout 
SECTION: stderr 
-bash-4.2# METAstr: stdout 
METAstr: stderr 
METAend: stdout 
METAend: stderr 

und zu versuchen, log ‚Abschnitt‘ Ich denke, Fouls auf meine FDs so folgendes: ‚Abschnitt‘ alle Meta-Ausgabe anmelden wird gedruckt nach der Rückkehr des Skripts

#!/bin/bash 

rm *.log 
NAMED_PIPE="$(mktemp -u /tmp/pipe.XXXX)" 
mknod $NAMED_PIPE p 
tee <$NAMED_PIPE "./meta.log" & 

section() { 
    echo SECTION: stdout 
    echo SECTION: stderr >&2 
} 

# link stdout->3 & stderr->4 and save stdout & stderr 
exec 3>&1 4>&2 &> "$NAMED_PIPE" 
echo METAstr: stdout 
echo METAstr: stderr >&2 

# restore stdout & stderr 
exec 1>&3 2>&4 
# sleep 1  # I think an additional delay prevents the possible race condition I'm seeing 
# exec 1>&3- 2>&4- ... I think this would restore but close 3 & 4? 
# do I need another named pipe here? 
section 2>&1 # | tee section.log 

# re-link to same pipe 
exec 3>&1 4>&2 &> "$NAMED_PIPE" 
echo METAend: stdout 
echo METAend: stderr >&2 

Ohne zu versuchen, exec hängt mir auf:

-bash-4.2# ./test.sh 
METAstr: stdout 
METAstr: stderr 
SECTION: stdout 
SECTION: stderr 

EDIT1:

Inhalt von meta.log ein N ach der Ausführung des Skripts, ohne versuchen zu tee section:

[[email protected] tmp]# cat meta.log 
METAstr: stdout 
METAstr: stderr 
METAend: stdout 
METAend: stderr 

Es die Endung Meldungen protokolliert, die tee nicht beendet, bis das Skript tut

EDIT2: Revision von EDIT1. Ich denke, es ist eine Wettlaufbedingung. Ich denke, die FDs sind werden geschlossen - aber sie sind nicht geschlossen, wenn die endgültigen Echo-Befehle passieren.

Antwort

0

Ich wollte nur das gleiche schreiben. Es ist eine Wettlaufbedingung. Die zweite Exec schließt das Schreibende in Ihrem Prozess und signalisiert einen EOF zum Abschlag. tee möchte beenden, wenn es das EOF bekommt. Wenn es zu dem Zeitpunkt beendet wird, zu dem Sie die letzte Exec aufrufen, wird die letzte Exec blockiert. Wenn es zu diesem Zeitpunkt noch nicht verlassen wurde, wird es nicht blockiert, weil ein Leseende des FIFO noch offen ist.

Jede Verzögerung macht es wahrscheinlicher, dass das T-Shirt zu diesem Zeitpunkt verlassen wird. Das Ablaichen eines Prozesses macht es sehr wahrscheinlich. Ich fand mit Staking (was das Programm etwas verlangsamt) es ist ungefähr 50/50.

+0

Genau. Ich kann näher kommen - aber dann starte ich eine endlose Schleife von 'stdin', die zu" t-stück "geleitet wird und die Ausgabe von diesem wird direkt zurück zu" tee "gesendet –

Verwandte Themen