GNU/Linux >> Linux Esercitazione >  >> Linux

Come scrivo stderr su un file mentre uso tee con una pipe?

Presumo che tu voglia ancora vedere STDERR e STDOUT sul terminale. Potresti scegliere la risposta di Josh Kelley, ma trovo che mantenere un tail intorno in background che emette il tuo file di registro molto hacker e goffo. Nota come devi mantenere un exra FD e successivamente eseguire la pulizia uccidendolo e tecnicamente dovresti farlo in un trap '...' EXIT .

C'è un modo migliore per farlo, e lo hai già scoperto:tee .

Solo, invece di usarlo solo per il tuo stdout, prendi una maglietta per stdout e una per stderr. Come realizzerai questo? Sostituzione del processo e reindirizzamento dei file:

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

Dividiamolo e spieghiamo:

> >(..)

>(...) (sostituzione del processo) crea un FIFO e lascia tee ascoltalo. Poi usa > (reindirizzamento file) per reindirizzare lo STDOUT di command al FIFO che il tuo primo tee è in ascolto.

Stessa cosa per il secondo:

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

Usiamo di nuovo la sostituzione del processo per creare un tee processo che legge da STDIN e lo scarica in stderr.log . tee restituisce il suo input su STDOUT, ma poiché il suo input è il nostro STDERR, vogliamo reindirizzare tee 's STDOUT al nostro STDERR di nuovo. Quindi usiamo il reindirizzamento dei file per reindirizzare command 's STDERR all'input del FIFO (tee 's STDIN).

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

La sostituzione del processo è una di quelle cose davvero adorabili che ottieni come bonus scegliendo bash come shell anziché sh (POSIX o Bourne).

In sh , dovresti fare le cose manualmente:

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"

perché non semplicemente:

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

Questo reindirizza semplicemente stderr a stdout , quindi tee fa eco sia a log che a screen. Forse mi sto perdendo qualcosa, perché alcune delle altre soluzioni sembrano davvero complicate.

Nota: Dalla versione 4 di bash puoi usare |& come abbreviazione di 2>&1 | :

./aaa.sh |& tee -a log

Questo può essere utile per le persone che lo trovano tramite Google. Decommenta semplicemente l'esempio che vuoi provare. Naturalmente, sentiti libero di rinominare i file di output.

#!/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. Come posso convogliare una chiamata di sottoprocesso a un file di testo?

  2. Come scrivere un numero intero in un file binario usando Bash?

  3. Come aggiungere al file in C, utilizzando Apri in modalità O_APPEND su Linux?

  4. Come aggiungere a un file come sudo?

  5. Come trovare il file con name=php.ini su Linux usando il comando grep

Come scrivere uno script Bash con esempi

Come reindirizzare stderr a stdout in Bash

Procedura:un'introduzione all'uso di Git

Tutorial Unix Sed:come scrivere su un file usando Sed

Come riempire un file con FF usando dd?

Come rimuovere un file senza usare rm?