Bagaimana cara mengarahkan stderr dan stdout ke file yang berbeda dan juga ditampilkan di terminal?

30

Saya ingin melihat output dari perintah di terminal seolah-olah tidak ada pengalihan. Juga, stderr perlu diarahkan ke err.log dan stdout perlu diarahkan ke stdout.log.

Akan lebih baik juga memiliki salinan yang tepat dari apa yang ditampilkan di terminal, yaitu kesalahan dicetak sebagai dan ketika itu terjadi, dalam file terpisah: stdouterr.log.

balki
sumber
@Nuno Tidak bukan. OP ingin memiliki file yang berbeda untuk stdout dan stderr.
dogbane
@ sopan Ya, Anda benar. Maaf soal itu.
Nuno C. Inácio
Saya masih menemukan pertanyaan ini sangat akrab. Biarkan saya melihat ... Berikut ini adalah yang sangat mirip unix.stackexchange.com/q/4195/250 , dan ini yang terkait unix.stackexchange.com/q/1416/250
phunehehe

Jawaban:

37

Gunakan teeperintah sebagai berikut:

(cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log

3>&1 1>&2 2>&3 adalah cara Anda bertukar stderr dan stdout, karena tee hanya dapat menerima stdout.

Lihatlah perintah tee Unix untuk pengalihan lebih lanjut menggunakan tee.

dogbane
sumber
solusi yang bagus. Apakah ada cara untuk mendapatkan kode keluar cmd?
Turbanoff
2
@turbanoff Ganti cmddengan (cmd ; echo >exit_code.txt $?).
Parthian Shot
Saya percaya ini seharusnya lebih menjaga urutan hal-hal yang dihasilkan ke baris perintah:((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log)
TTT
5

Saya pikir masuk stdout dan stderr ke dua file yang berbeda adalah ide bagus. Apakah itu tidak membuat log asinkron? Jadi saya mencoba yang berikut ini:

  • stdout ke "stdout.log" (seperti yang disarankan dogbane)
  • stderror to "stderr.log" (seperti yang disarankan dogbane)
  • semua output ke "all.log" dan
  • masih dapat melihat output pada tampilan (di terminal terpisah!)

((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log) &> all.log

di terminal lain

tail -f --sleep-interval=2 all.log
Sreeni
sumber
Apakah tidak mungkin mengarahkan stderr langsung ke tty kedua? Maka tidak diperlukan file log.
Steven Lu
@ SevenLu ya, jika Anda tahu nama dan memiliki izin untuk menulis ke tty kedua yang bisa dilakukan.
Jasen
1
lebih mudah &| tee all.logpada akhir perintah daripada&> all.log
Jasen
@ Yasen: kedua kalinya saya melihat &|. Saya mengerti &>, |&juga, tapi apa &|artinya dalam konteks ini? Saya tidak dapat menemukan referensi sintaksis yang cocok, tidak di internet, bahkan tidak melihat halaman manual bash "bash (1)" ... Tx
Cbhihe
1
@Cbhihe sejauh yang saya bisa katakan itu tidak melakukan apa-apa, saya bermaksud mengatakan|&
Jasen
3

@ Duke, Terima kasih.
Saya menemukan cara lain juga yang menghemat sekitar aliran dalam urutan karena mereka akan dicetak tanpa pengalihan.

command 2> >(tee errlog | tee -a bothLog > /dev/tty ) | tee outlog | tee -a bothLog

Tetapi ini hanya bekerja pada cangkang yang mendukung substitusi proses.

balki
sumber
-2

coba ini :

command 2>&1 | tee bothLog
vasile
sumber
4
Halo vasile, ini tidak menjawab pertanyaan: balki membutuhkan file terpisah untuk stdout dan stderr, solusi Anda akan mencampur keduanya dalam aliran yang sama.
Mat
Mengapa orang menggabungkan stdout dan stderr bersama? Atau suruh orang lain melakukannya?
nurettin