Bedeutung von '2>> (Befehl)' Umleitung in Bash

18

Vor einiger Zeit habe ich ein Skript erstellt und einige Protokolldateien hinzugefügt, aber ich habe vergessen, wie die Umleitung für die Protokollierung funktioniert :-(

Der Kern davon ist:

#!/bin/bash

LOGFILE=/some/path/mylogfile

(
  # here go my commands which produce some stdout
  # and, if something goes wrong, also some stderr
) 1>>${LOGFILE} 2> >( tee -a ${LOGFILE} >&2 )

Wenn ich das Skript ausführe, druckt es nichts stdout, sondern nur das, was ankommt stderr. Logfile ${LOGFILE}erfasst sowohl stdout als auch stderr.

Wenn ich das Skript ausführe und auf meinem Terminal keine Ausgabe erfolgt, weiß ich, dass alles in Ordnung ist. Wenn eine Ausgabe vorliegt, weiß ich, dass ein Fehler aufgetreten ist, und kann die Protokolldatei überprüfen, um herauszufinden, wo das Problem liegt.

Der Teil der Umleitung, der mich jetzt verwirrt, ist die Syntax von: 2> >( some command )

Kann mir jemand erklären, was da los ist?

NZD
quelle

Antworten:

23

>(...)heißt Prozesssubstitution . Es lässt das "äußere" Programm in das "innere" Programm schreiben, als ob es eine Datei wäre.

In diesem Fall ist es Schreiben, stderran tee -a ${LOGFILE} >&2das angehängt LOGFILEund dann auch alles zurückgeschrieben wird stderr.

Der Umleitungsoperator kann für die Prozessersetzung in beide Richtungen gehen, sodass Sie wie in diesem Beispiel darauf schreiben oder daraus <(...)lesen können. Dies ist eine praktische Methode, um beispielsweise eine whileSchleife zu erstellen, ohne sie in einer Subshell auszuführen selbst.

Eric Renouf
quelle
5
Verstanden :-) Wenn ich ausführen echo <(date), es mir den Namen der substituierten Datei gibt: /dev/fd/63. Wenn ich ausführen cat <(date), gibt es mir das Datum, dh den Inhalt der substituierten Datei: Fri Nov 18 14:11:09 NZDT 2016.
NZD
@NZD, ja - aber stellen Sie sich nicht vor, dass es sich um eine reguläre Datei handelt - was Sie sehen, /devist ein Name für die Pipe zwischen den Prozessen.
Toby Speight
Wird diese Technik verwendet, weil stderr ( teein diesem Fall) nicht weitergeleitet werden kann ?
bli
@bli Ja, da stdout bereits an eine andere Stelle umgeleitet wird, scheint mir dies der einfachste Weg zu sein, teestderr und stdout voneinander zu trennen.
Eric Renouf