2009-02-20 5 views

Antwort

41
echo "hey hey, we're the monkees" | tee /dev/tty | gzip --stdout > my_log.gz 

Wie in den Kommentaren darauf hingewiesen, /dev/stdout Macht arbeiten unter Umständen besser als /dev/tty.

+0

_A_w_e_s_o_m_e_. Vielen Dank. –

+3

Was macht/dev/tty da? Die ursprüngliche Frage wollte die Ausgabe auf Standardausgabe, nicht unbedingt auf dem Terminal. –

+4

/dev/tty ist ein Synonym für das aktuelle Terminal. Der Fragesteller verwendete "standard out" in der üblichen Weise, um das aktuelle Terminal zu meinen, anstatt eine strengere Definition des Begriffs. –

16

Haben Sie eine schöne Tasse tee!

Der tee Befehl kopiert Standardeingabe auf der Standardausgabe und auch für alle Dateien als Argumente gegeben. Dies ist nützlich, wenn Sie wollen nicht nur einige Daten nach unten ein Rohr senden, sondern auch auf

Kopie speichern Als ich einen langsamen Nachmittag mit bin, hier einige glorreich illustrative ascii-art ...

  +-----+     +---+     +-----+ 
stdin -> |cmd 1| -> stdout -> |tee| -> stdout -> |cmd 2| 
      +-----+     +---+     +-----+ 
             | 
             v 
            file 

Als greyfade in einer anderen Antwort zeigt die ‚Datei‘ braucht keine reguläre Datei sein, aber könnte FIFO sein, Ihnen Rohr lassen, die Ausgabe in einen dritten Befehl Tee würde.

  +-----+     +---+     +-----+ 
stdin -> |cmd 1| -> stdout -> |tee| -> stdout -> |cmd 2| 
      +-----+     +---+     +-----+ 
             | 
             v 
            FIFO 
             | 
             v 
            +-----+ 
            |cmd 3| 
            +-----+ 
+0

Aber ich möchte die Zwischendatei im laufenden Betrieb gzip. Ist das nur mit Tee möglich? –

+0

ja, schrieb der andere Paul eine schöne prägnante antworte, während ich mit einem ASCII-Kunst-Diagramm herumgespielt habe :) –

+1

Aber +1 für die ausgezeichnete Erklärung. –

46

Eine andere Art und Weise (eine Shell wie bash oder zsh vorausgesetzt):

echo "hey hey, we're the monkees" | tee >(gzip --stdout > my_log.gz) 

Die zugegebenermaßen merkwürdige >() Syntax ist im Grunde die folgenden:

  • neue FIFO in /tmp/ erstellen (in der Regel etwas)
  • Befehl innerhalb () ausführen und b ind das FIFO zu stdin auf diesem Unterbefehl
  • FIFO-Dateinamen an die Befehlszeile zurückgeben.

Was tee sehen landet, dann ist so etwas wie:

tee /tmp/arjhaiX4 

Alle gzip sieht, ist seine Standardeingabe.

Für Bash, siehe man bash für Details. Es ist im Abschnitt redirection. Für Zsh, siehe man zshexpn unter der Überschrift "Prozesssubstitution."

Soweit ich das beurteilen kann, unterstützen die Korn Shell, Varianten der klassischen Bourne Shell (einschließlich Asche und Bindestrich) und die C Shell diese Syntax nicht.

+0

Cool, ich lerne selbst etwas hier. Können Sie näher erläutern, was dort passiert? –

+0

Ich werde meinen Beitrag bearbeiten. – greyfade

+0

Wenn ich es richtig gelesen habe, anstatt eine Datei an T-Stück zu geben, haben Sie es die Kopie als Eingabe in eckigen Ausdruck senden, der die gzip-Ausgabe in eine andere Datei schreibt. Die unkomprimierten Daten verlassen T-Shirt als normal auf stdout –

6

nur einen Weg zu schreiben, die sich nicht berühren Platte mit sich bringt:

echo "hey hey, we're the monkees" | (exec 1>&3 && tee /proc/self/fd/3 | gzip --stdout > my_log.gz) 
+0

Was, du meinst/tmp ist auf einer Festplatte?!?!?!? – SamB

+0

Aus Sicherheitsgründen ist es. – Joshua