Untuk menulis stderr ke layar dan menulis KEDUA stderr dan stdout ke file - DAN memiliki baris untuk stderr dan stdout keluar dalam urutan yang sama seperti jika keduanya ditulis ke layar:
Ternyata menjadi masalah yang sulit, terutama bagian tentang memiliki "urutan yang sama" yang Anda harapkan jika Anda hanya menulisnya di layar. Secara sederhana: Tulis masing-masing ke file sendiri, lakukan beberapa sihir proses latar belakang untuk menandai setiap baris (dalam setiap file) dengan waktu yang tepat garis itu diproduksi, dan kemudian: "ekor - ikuti" file stderr ke layar , tetapi untuk melihat KEDUA "stderr" dan "stdout" bersama - secara berurutan - urutkan kedua file (dengan tanda waktu yang tepat pada setiap baris) bersamaan.
Kode:
# 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'"
Ya, ini tampaknya rumit, dan menghasilkan 4 file output (2 di antaranya dapat Anda hapus). Tampaknya ini adalah masalah yang sulit untuk dipecahkan, jadi butuh beberapa mekanisme.
Pada akhirnya, untuk melihat hasil dari KEDUA stdout dan stderr dalam urutan yang Anda harapkan, jalankan ini:
cat $pth/$ffn.out.txt $pth/$ffn.err.txt | sort
Satu-satunya alasan urutannya setidaknya sangat dekat dengan apa yang seharusnya dimiliki stdout dan stderr hanya pergi ke layar adalah: Setiap baris ditandai dengan cap waktu hingga milidetik.
Untuk melihat stderr di layar saat proses berjalan, gunakan ini:
tail -f $pth/$ffn.out
Harapan yang membantu seseorang keluar, yang tiba di sini lama setelah pertanyaan awal diajukan.