Aby napisać stderr na screen i napisać ZARÓWNO stderr i stdout do pliku - ORAZ niech wiersze stderr i stdout wychodzą w takiej samej kolejności, jak gdyby oba były zapisane na ekranie:
Okazuje się, że jest to trudny problem, zwłaszcza część o posiadaniu „tej samej sekwencji”, której można by się spodziewać, gdyby po prostu napisać je na ekranie. W prostych słowach: zapisz każdy do własnego pliku, zrób trochę magii w tle, aby oznaczyć każdą linię (w każdym pliku) dokładnym czasem, w którym linia została utworzona, a następnie: „ogon - śledź” plik stderr na ekran , ale aby zobaczyć ZARÓWNO „stderr” i „stdout” razem - po kolei - posortuj oba pliki (z oznaczeniem dokładnego czasu w każdym wierszu) razem.
Kod:
# 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'"
Tak, wydaje się to skomplikowane i daje w wyniku 4 pliki wyjściowe (z których 2 można usunąć). Wygląda na to, że jest to trudny problem do rozwiązania, więc wymagało kilku mechanizmów.
Na koniec, aby zobaczyć wyniki ZARÓWNO stdout i stderr w oczekiwanej sekwencji, uruchom to:
cat $pth/$ffn.out.txt $pth/$ffn.err.txt | sort
Jedynym powodem, dla którego sekwencja jest co najmniej bardzo zbliżona do tego, co by się stało, gdyby zarówno stdout, jak i stderr po prostu poszły na ekran, jest: Każda linia jest oznaczona znacznikiem czasu z dokładnością do milisekundy.
Aby zobaczyć stderr na ekranie w trakcie procesu, użyj tego:
tail -f $pth/$ffn.out
Mam nadzieję, że to pomoże komuś, kto przybył tu długo po zadaniu pierwotnego pytania.