Bagaimana saya bisa mencapainya?
cmd >> file1 2>&1 1>>file2
Artinya, stdout dan stderr harus diarahkan ke satu file (file1) dan hanya stdout (file2) yang harus diarahkan ke yang lain (keduanya dalam mode tambahan)?
Masalahnya adalah ketika Anda mengarahkan ulang output Anda, itu tidak tersedia lagi untuk redirect berikutnya. Anda dapat menyalurkan ke tee
dalam subkulit untuk menjaga output untuk pengalihan kedua:
( cmd | tee -a file2 ) >> file1 2>&1
atau jika Anda ingin melihat output di terminal:
( cmd | tee -a file2 ) 2>&1 | tee -a file1
Untuk menghindari menambahkan stderr dari yang pertama tee
ke file1
, Anda harus mengarahkan stderr dari perintah Anda ke beberapa deskriptor file (misalnya 3), dan kemudian menambahkan ini ke stdout lagi:
( 2>&3 cmd | tee -a file2 ) >> file1 3>&1
# or
( 2>&3 cmd | tee -a file2 ) 3>&1 | tee -a file1
(terima kasih @ fra-san)
Dengan zsh
:
cmd >& out+err.log > out.log
Dalam mode tambahkan:
cmd >>& out+err.log >> out.log
Di zsh
, dan asalkan mult_ios
opsi belum dinonaktifkan, ketika file deskriptor (di sini 1) dialihkan beberapa kali untuk menulis, maka shell mengimplementasikan built-in tee
untuk menduplikasi output ke semua target.
out+err
danout
maksud di sini. Nama file? Streaming akan diarahkan?cmd >& file1 > file2
Anda dapat: menandai stdout (menggunakan sed UNBUFFERED, yaitu:)
sed -u ...
, memiliki stderr juga pergi ke stdout (tidak ditandai, karena tidak melewati sed penandaan itu), dan dengan demikian dapat membedakan 2 di logfile yang dihasilkan.Berikut ini: lambat (Ini dapat dioptimalkan secara serius, dengan menggunakan untuk contoh skrip perl alih-alih sementara ...; lakukan ...; selesai, misalnya, yang akan memunculkan subkulit & perintah di setiap baris!), Aneh (sepertinya saya memerlukan 2 {} stage untuk di satu mengubah nama stdout dan kemudian yang lain menambahkan "jatuh melalui" stderr untuk itu), dll. Tapi itu adalah: " bukti konsep ", yang akan mencoba untuk menjaga urutan keluaran sebanyak-banyaknya dari stdout & stderr:
sumber
ls unknown
) untuk mencetak sesuatu di stderr?>&2 echo "error"
akan baik-baik saja. (2)tee
dapat menambahkan beberapa file sekaligus. (3) Mengapa tidak hanyacat
bukangrep "^"
? (4) skrip Anda akan gagal ketika output stderr dimulai_stdout_
. (5) Kenapa?ls loop
akan menghasilkan output pada stdout dan stderr, dicampur (sebagai alternatif), dalam urutan yang terkendali, sehingga kita dapat memeriksa bahwa kita tetap memesan stderr / stdout meskipun ada penandaan stdout 2): gnu tail, mungkin, tapi tidak ekor biasa (mis., pada aix.). 3): grep "^" juga menampilkan kedua nama file. 4): ini dapat diubah oleh variabel. 5): contoh berbelit-belit bekerja pada oses lama (ex, aix tua) di mana saya mengujinya (tidak ada perl tersedia).uniquetag="banaNa11F453355B28E1158D4E516A2D3EDF96B3450406
...)Jika urutan output harus: stdout maka stderr ; tidak ada solusi dengan pengalihan saja.
Stderr harus disimpan ke file temporal
Deskripsi:
Satu-satunya cara untuk mengarahkan ulang satu output (seperti stdout atau stderr) ke dua file adalah dengan mereproduksi. Perintah
tee
adalah alat yang benar untuk mereproduksi konten deskriptor file. Jadi, ide awal untuk memiliki satu output pada dua file adalah menggunakan:Itu mereproduksi stdin tee ke kedua file (1 & 2) meninggalkan output tee masih belum digunakan. Tetapi kita perlu menambahkan (menggunakan
-a
) dan hanya perlu satu salinan. Ini menyelesaikan kedua masalah:Untuk memasok
tee
dengan stdout (yang harus diulang) kita perlu mengkonsumsi stderr langsung dari perintah. Salah satu cara, jika pesanan tidak penting (urutan output akan (kemungkinan besar) akan dipertahankan seperti yang dihasilkan, yang mana output pertama akan disimpan terlebih dahulu). Antara:cmd 2>>file1 | tee -a file2 >>file1
cmd 2>>file1 > >( tee -a file2 >>file1 )
( cmd | tee -a file2 ) >> file1 2>&1
Opsi 2 hanya berfungsi di beberapa shell. Opsi 3 menggunakan subkulit tambahan (lebih lambat) tetapi gunakan nama file hanya sekali.
Tetapi jika stdout harus menjadi yang pertama (output pesanan mana pun yang dihasilkan) kita perlu menyimpan stderr untuk menambahkannya ke file di akhir (solusi pertama diposting).
sumber
sponge
halnya:(cmd | tee -a out >> out+err) 2>&1 | sponge >> out+err
Untuk kepentingan keragaman:
Jika sistem Anda mendukung
/dev/stderr
, makaakan bekerja. Output standar dari
cmd
dikirim ke stdout dan stderr dari pipa. Kesalahan standarcmd
memotongtee
dan keluar stderr dari pipa.Begitu
cmd
, dancmd
, intermixed.Maka masalah sederhana mengirim aliran ke file yang benar.
Seperti hampir semua pendekatan seperti ini (termasuk jawaban Stéphane ),
file1
mungkin membuat garis tidak sesuai.sumber