GNU/Linux >> Znalost Linux >  >> Linux

Jak zapíšu stderr do souboru při použití tee s potrubím?

Předpokládám, že chcete na terminálu stále vidět STDERR a STDOUT. Můžete jít po odpovědi Joshe Kelleyho, ale zjistil jsem, že si nechávám tail kolem na pozadí, což vypíše váš log soubor velmi hackerský a neohrabaný. Všimněte si, jak si musíte ponechat exra FD a poté provést vyčištění jeho zabitím a technicky by to mělo být provedeno v trap '...' EXIT .

Existuje lepší způsob, jak to udělat, a už jste ho objevili:tee .

Pouze místo toho, abyste jej používali pouze pro svůj stdout, mějte tričko pro stdout a jedno pro stderr. Jak toho dosáhnete? Nahrazení procesu a přesměrování souboru:

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

Pojďme si to rozdělit a vysvětlit:

> >(..)

>(...) (záměna procesu) vytvoří FIFO a nechá tee poslouchej to. Potom použije > (přesměrování souboru) k přesměrování STDOUT z command na FIFO, že vaše první tee poslouchá dál.

Totéž pro druhou:

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

K vytvoření tee opět použijeme substituci procesů proces, který čte ze STDIN a ukládá jej do stderr.log . tee odešle svůj vstup zpět na STDOUT, ale protože jeho vstup je náš STDERR, chceme přesměrovat tee 's STDOUT do našeho STDERR znovu. Pak použijeme přesměrování souboru k přesměrování command 's STDERR na vstup FIFO (tee STDIN).

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

Náhrada procesů je jedna z těch opravdu krásných věcí, které získáte jako bonus za volbu bash jako váš shell na rozdíl od sh (POSIX nebo Bourne).

V sh , budete muset dělat věci ručně:

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"

proč ne jednoduše:

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

Toto jednoduše přesměruje stderr na stdout , takže tee se ozývá jak do logu, tak do obrazovky. Možná mi něco uniká, protože některá další řešení se zdají být opravdu složitá.

Poznámka: Od verze bash 4 můžete používat |& jako zkratka pro 2>&1 | :

./aaa.sh |& tee -a log

To může být užitečné pro lidi, kteří to najdou přes google. Jednoduše odkomentujte příklad, který chcete vyzkoušet. Samozřejmě můžete výstupní soubory přejmenovat.

#!/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. Jak napsat soubor s C v Linuxu?

  2. Jak převedu volání podprocesu do textového souboru?

  3. Jak zapsat celé číslo do binárního souboru pomocí Bash?

  1. Jak odstranit soubor bez použití rm?

  2. Jak změnit soubor na místě pomocí awk? (jako u sed -i)

  3. Zachycení STDERR a STDOUT do souboru pomocí tee

  1. Jak zapsat soubor do jiného?

  2. Jak přesměrovat pouze Stderr?

  3. Jak duplikovat soubor bez kopírování jeho dat pomocí Btrfs?