Para escribir stderr en la pantalla y escribir AMBOS stderr y stdout en un archivo, Y que las líneas para stderr y stdout salgan en la misma secuencia que lo harían si ambas se escribieran en la pantalla:
Resulta ser un problema difícil, especialmente la parte de tener "la misma secuencia" que esperaría si simplemente los escribiera en la pantalla. En términos simples: escriba cada uno en su propio archivo, haga un poco de magia de proceso en segundo plano para marcar cada línea (en cada archivo) con la hora exacta en que se produjo la línea, y luego: "seguir - seguir" el archivo stderr en la pantalla , pero para ver AMBOS "stderr" y "stdout" juntos, en secuencia, clasifique los dos archivos (con marcas de tiempo exacto en cada línea) juntos.
Código:
# Set the location of output and the "first name" of the log file(s)
pth=$HOME
ffn=my_log_filename_with_no_extension
date >>$pth/$ffn.out
date >>$pth/$ffn.err
# Start background processes to handle 2 files, by rewriting each one line-by-line as each line is added, putting a label at front of line
tail -f $pth/$ffn.out | perl -nle 'use Time::HiRes qw(time);print substr(time."0000",0,16)."|1|".$_' >>$pth/$ffn.out.txt &
tail -f $pth/$ffn.err | perl -nle 'use Time::HiRes qw(time);print substr(time."0000",0,16)."|2|".$_' >>$pth/$ffn.err.txt &
sleep 1
# Remember the process id of each of 2 background processes
export idout=`ps -ef | grep "tail -f $pth/$ffn.out" | grep -v 'grep' | perl -pe 's/\s+/\t/g' | cut -f2`
export iderr=`ps -ef | grep "tail -f $pth/$ffn.err" | grep -v 'grep' | perl -pe 's/\s+/\t/g' | cut -f2`
# Run the command, sending stdout to one file, and stderr to a 2nd file
bash mycommand.sh 1>>$pth/$ffn.out 2>>$pth/$ffn.err
# Remember the exit code of the command
myexit=$?
# Kill the two background processes
ps -ef | perl -lne 'print if m/^\S+\s+$ENV{"idout"}/'
echo kill $idout
kill $idout
ps -ef | perl -lne 'print if m/^\S+\s+$ENV{"iderr"}/'
echo kill $iderr
kill $iderr
date
echo "Exit code: $myexit for '$listname', list item# '$ix', bookcode '$bookcode'"
Sí, esto parece elaborado, y da como resultado 4 archivos de salida (2 de los cuales puede eliminar). Parece que este es un problema difícil de resolver, por lo que tomó varios mecanismos.
Al final, para ver los resultados de AMBOS stdout y stderr en la secuencia que esperarías, ejecuta esto:
cat $pth/$ffn.out.txt $pth/$ffn.err.txt | sort
La única razón por la que la secuencia es al menos muy cercana a lo que hubiera sido que stdout y stderr simplemente hubieran ido a la pantalla es: Cada línea está marcada con una marca de tiempo hasta el milisegundo.
Para ver stderr en la pantalla a medida que avanza el proceso, use esto:
tail -f $pth/$ffn.out
Espero que ayude a alguien, que llegó aquí mucho después de que se hizo la pregunta original.