Tee tidak mendapatkan seluruh output dari pipa

12

Saya memiliki skrip yang menjalankan perintah seperti:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH;./some_app -i $INDEX | tee $LOG
echo "Number of errors: $(grep "ERROR" $LOG | wc -l)"

Masalahnya mungkin di pipa tee. Tampaknya tidak mendapatkan seluruh output. Ketika aplikasi berhenti beberapa baris terakhir dari output (biasanya yang mengandung kesalahan fatal) hilang. Ketika saya menjalankan aplikasi tanpa pipa teesaya mendapatkannya di output.

Bagaimana saya bisa memaksa skrip untuk menunggu tee menyelesaikan proses semua output?

Ladislav Mrnka
sumber
Apakah ini berfungsi baik jika Anda tee ke file, bukan stdout?
Pilot6

Jawaban:

23

Kesalahan fatal mungkin muncul di STDERR (2), bukan STDOUT (1). Anda dapat mengarahkan kembali STDERR ke dalam STDOUT 2>&1dan kemudian pipa tersebut akan menangkapnya juga.

./some_app -i $INDEX 2>&1 | tee $LOG

Jika Anda memiliki masalah buffering di bagian atas, Anda bisa memaksanya menjadi status tidak terbaca:

stdbuf -o0 ./some_app -i $INDEX 2>&1 | tee $LOG
Oli
sumber
Bagus, kita semakin dekat. Sekarang saya melihat bahwa kesalahan fatal sedang dicetak tetapi sekali lagi tidak lengkap. Baris dengan kesalahan hanya berakhir di tengah dan gema output berlanjut. Masih ada beberapa masalah dengan buffer flushing atau hanya menunggu bagian itu selesai.
Ladislav Mrnka
Diedit. Agak langka dalam pengalaman saya bahwa sesuatu yang benar-benar menyelinap melalui buffer saat keluar tetapi itu layak untuk dicoba.
Oli
1
Selesai! Terima kasih. Saya mungkin mengajukan terlalu banyak pertanyaan, tetapi adakah yang mengerti mengapa saya harus mematikan buffering ketika melakukan piping ke proses lain?
Ladislav Mrnka
@ Oli Yang sangat bagus!
Pilot6
6

Karena pesan kesalahan biasanya ditampilkan pada STDERR (File descriptor 2), Anda perlu mengarahkan STDOUT dan STDERR ke tee:

./some_app -i "$INDEX" |& tee "$LOG"

Ketika Anda melakukannya, ./some_app -i $INDEX | tee $LOGAnda hanya mengarahkan STDOUT ke tee.

|& akan menyebabkan STDOUT dan STDERR dialihkan.

Jika Anda tidak dapat mengarahkan kembali hanya STDOUT (Saat Anda dulu):

./some_app -i "$INDEX" | tee "$LOG"

Di sisi lain, jika Anda hanya ingin mengarahkan ulang STDERR:

./some_app -i "$INDEX" 2>&1 >/dev/null | tee "$LOG"
heemayl
sumber