GNU/Linux >> Tutoriels Linux >  >> Linux

Comment écrire stderr dans un fichier tout en utilisant tee avec un tuyau ?

Je suppose que vous voulez toujours voir STDERR et STDOUT sur le terminal. Vous pourriez opter pour la réponse de Josh Kelley, mais je trouve que garder un tail autour en arrière-plan qui génère votre fichier journal très hackish et maladroit. Remarquez comment vous devez conserver un exra FD et faire le nettoyage par la suite en le tuant et, techniquement, vous devriez le faire dans un trap '...' EXIT .

Il existe une meilleure façon de procéder, et vous l'avez déjà découverte :tee .

Seulement, au lieu de simplement l'utiliser pour votre stdout, ayez un tee pour stdout et un pour stderr. Comment allez-vous accomplir cela ? Substitution de processus et redirection de fichiers :

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

Séparons-le et expliquons :

> >(..)

>(...) (substitution de processus) crée un FIFO et laisse tee écoutez dessus. Ensuite, il utilise > (redirection de fichier) pour rediriger le STDOUT de command au FIFO que votre premier tee écoute.

Même chose pour le second :

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

Nous utilisons à nouveau la substitution de processus pour créer un tee processus qui lit à partir de STDIN et le vide dans stderr.log . tee renvoie son entrée sur STDOUT, mais puisque son entrée est notre STDERR, nous voulons rediriger tee 's STDOUT à notre STDERR à nouveau. Ensuite, nous utilisons la redirection de fichiers pour rediriger command 's STDERR à l'entrée de la FIFO (tee 's STDIN).

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

La substitution de processus est l'une de ces choses vraiment adorables que vous obtenez en bonus en choisissant bash comme votre shell par opposition à sh (POSIX ou Bourne).

En sh , il faudrait faire les choses manuellement :

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"

pourquoi pas simplement :

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

Cela redirige simplement stderr à stdout , donc tee fait écho à la fois au journal et à l'écran. Peut-être qu'il me manque quelque chose, car certaines des autres solutions semblent vraiment compliquées.

Remarque : Depuis la version 4 de bash, vous pouvez utiliser |& comme abréviation de 2>&1 | :

./aaa.sh |& tee -a log

Cela peut être utile pour les personnes qui trouvent cela via google. Décommentez simplement l'exemple que vous voulez essayer. Bien sûr, n'hésitez pas à renommer les fichiers de sortie.

#!/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. Comment écrire un fichier avec C sous Linux ?

  2. Comment diriger un appel de sous-processus vers un fichier texte ?

  3. Comment écrire un entier dans un fichier binaire à l'aide de Bash ?

  4. Comment ajouter au fichier en C, en utilisant Open in O_APPEND Mode sous Linux ?

  5. Comment ajouter à un fichier en tant que sudo?

Comment écrire un script bash avec des exemples

Comment rediriger stderr vers stdout dans Bash

Comment écrire un fichier dans un autre ?

Comment :une introduction à l'utilisation de Git

Tutoriel Unix Sed :comment écrire dans un fichier à l'aide de Sed

Capture de STDERR et STDOUT dans un fichier à l'aide de tee