Pour écrire stderr sur écran et écrire les deux stderr et stdout dans un fichier - ET faire en sorte que les lignes pour stderr et stdout sortent dans le même ordre que si elles étaient écrites sur l'écran:
Se révèle être un problème difficile, en particulier la partie concernant la "même séquence" à laquelle vous vous attendez si vous les écriviez simplement à l'écran. En termes simples: écrivez chacun dans son propre fichier, faites un peu de magie en arrière-plan pour marquer chaque ligne (dans chaque fichier) avec l'heure exacte à laquelle la ligne a été produite, puis: "tail --follow" le fichier stderr à l'écran , mais pour voir les deux "stderr" et "stdout" ensemble - dans l'ordre - trier les deux fichiers (avec des marquages d'heure exacte sur chaque ligne) ensemble.
Code:
# 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'"
Oui, cela semble élaboré et il en résulte 4 fichiers de sortie (dont 2 que vous pouvez supprimer). Il semble que ce soit un problème difficile à résoudre, il a donc fallu plusieurs mécanismes.
En fin de compte, pour voir les résultats des deux stdout et stderr dans la séquence que vous attendez, exécutez ceci:
cat $pth/$ffn.out.txt $pth/$ffn.err.txt | sort
La seule raison pour laquelle la séquence est au moins très proche de ce qu'elle aurait été si stdout et stderr étaient simplement passés à l'écran est: chaque ligne est marquée avec un horodatage jusqu'à la milliseconde.
Pour voir stderr à l'écran au cours du processus, utilisez ceci:
tail -f $pth/$ffn.out
J'espère que cela aide quelqu'un qui est arrivé ici longtemps après que la question initiale a été posée.