GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie schreibe ich stderr in eine Datei, während ich tee mit einer Pipe verwende?

Ich gehe davon aus, dass Sie STDERR und STDOUT weiterhin auf dem Terminal sehen möchten. Sie könnten sich für Josh Kelleys Antwort entscheiden, aber ich finde, dass Sie einen tail behalten herum im Hintergrund, der Ihre Protokolldatei sehr hackish und klobig ausgibt. Beachten Sie, wie Sie einen Exra-FD behalten und danach aufräumen müssen, indem Sie ihn töten, und das sollte technisch gesehen in einem trap '...' EXIT geschehen .

Es gibt einen besseren Weg, dies zu tun, und Sie haben ihn bereits entdeckt:tee .

Nur, anstatt es nur für Ihre stdout zu verwenden, haben Sie ein T-Stück für stdout und eines für stderr. Wie werden Sie dies erreichen? Prozesssubstitution und Dateiumleitung:

command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)

Teilen wir es auf und erklären es:

> >(..)

>(...) (Process Substitution) erstellt einen FIFO und lässt tee hör drauf. Dann verwendet es > (Dateiumleitung), um die STDOUT von command umzuleiten zum FIFO, dass Ihre erste tee hört zu.

Dasselbe für die zweite:

2> >(tee -a stderr.log >&2)

Wir verwenden wieder die Prozesssubstitution, um einen tee zu erstellen Prozess, der von STDIN liest und es in stderr.log ausgibt . tee gibt seine Eingabe auf STDOUT zurück, aber da seine Eingabe unser STDERR ist, möchten wir tee umleiten 's STDOUT wieder zu unserem STDERR. Dann verwenden wir die Dateiumleitung, um command umzuleiten 's STDERR an den Eingang des FIFO (tee 's STDIN).

Siehe http://mywiki.wooledge.org/BashGuide/InputAndOutput

Die Prozessersetzung ist eines dieser wirklich schönen Dinge, die Sie als Bonus erhalten, wenn Sie bash wählen als Ihre Shell im Gegensatz zu sh (POSIX oder Bourne).

In sh , müssten Sie die Dinge manuell erledigen:

out="${TMPDIR:-/tmp}/out.$$" err="${TMPDIR:-/tmp}/err.$$"
mkfifo "$out" "$err"
trap 'rm "$out" "$err"' EXIT
tee -a stdout.log < "$out" &
tee -a stderr.log < "$err" >&2 &
command >"$out" 2>"$err"

warum nicht einfach:

./aaa.sh 2>&1 | tee -a log

Dies leitet einfach stderr um bis stdout , also echos sowohl zum Log als auch zum Screen. Vielleicht übersehe ich etwas, weil einige der anderen Lösungen wirklich kompliziert erscheinen.

Hinweis: Seit der Bash-Version 4 können Sie |& verwenden als Abkürzung für 2>&1 | :

./aaa.sh |& tee -a log

Dies kann für Leute nützlich sein, die dies über Google finden. Kommentieren Sie einfach das Beispiel aus, das Sie ausprobieren möchten. Natürlich können Sie die Ausgabedateien auch umbenennen.

#!/bin/bash

STATUSFILE=x.out
LOGFILE=x.log

### All output to screen
### Do nothing, this is the default


### All Output to one file, nothing to the screen
#exec > ${LOGFILE} 2>&1


### All output to one file and all output to the screen
#exec > >(tee ${LOGFILE}) 2>&1


### All output to one file, STDOUT to the screen
#exec > >(tee -a ${LOGFILE}) 2> >(tee -a ${LOGFILE} >/dev/null)


### All output to one file, STDERR to the screen
### Note you need both of these lines for this to work
#exec 3>&1
#exec > >(tee -a ${LOGFILE} >/dev/null) 2> >(tee -a ${LOGFILE} >&3)


### STDOUT to STATUSFILE, stderr to LOGFILE, nothing to the screen
#exec > ${STATUSFILE} 2>${LOGFILE}


### STDOUT to STATUSFILE, stderr to LOGFILE and all output to the screen
#exec > >(tee ${STATUSFILE}) 2> >(tee ${LOGFILE} >&2)


### STDOUT to STATUSFILE and screen, STDERR to LOGFILE
#exec > >(tee ${STATUSFILE}) 2>${LOGFILE}


### STDOUT to STATUSFILE, STDERR to LOGFILE and screen
#exec > ${STATUSFILE} 2> >(tee ${LOGFILE} >&2)


echo "This is a test"
ls -l sdgshgswogswghthb_this_file_will_not_exist_so_we_get_output_to_stderr_aronkjegralhfaff
ls -l ${0}

Linux
  1. Wie leite ich nur Stderr um?

  2. Wie leite ich einen Unterprozessaufruf an eine Textdatei weiter?

  3. Wie schreibe ich mit Bash Integer in eine Binärdatei?

  4. Wie kann ich als sudo an eine Datei anhängen?

  5. Wie fülle ich eine Datei mit FF mit dd auf?

So schreiben Sie ein Bash-Skript mit Beispielen

So leiten Sie stderr in Bash auf stdout um

Gewusst wie:Eine Einführung in die Verwendung von Git

Unix Sed Tutorial:So schreiben Sie mit Sed in eine Datei

Wie fügt man an eine Datei in C an, indem man Open in O_APPEND Mode unter Linux verwendet?

So finden Sie eine Datei mit name=php.ini unter Linux mit dem Befehl grep