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)?
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)?
Jawaban:
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.
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:
#basic principle (some un-necessary "{}" to visually help see the layers):
# { { complex command ;} | sed -e "s/^/TAGstdout/" ;} 2>&1 | read_stdin_and_redispatch
#exemple:
# complex command = a (slowed) ls of several things (some existing, others not)
# to see if the order of stdout&stderr is kept
#preparation, not needed for the "proof of concept", but needed for our specific exemple setup:
\rm out.file out_AND_err.file unknown unknown2
touch existing existing2 existing3
#and the (slow, too many execs, etc) "proof of concept":
uniquetag="_stdout_" # change this to something unique, that will NOT appear in all the commands outputs...
# avoid regexp characters ("+" "?" "*" etc) to make it easy to remove with another sed later on.
{
{ for f in existing unknown existing2 unknown2 existing3 ; do ls -l "$f" ; sleep 1; done ;
} | sed -u -e "s/^/${uniquetag}/" ;
} 2>&1 | while IFS="" read -r line ; do
case "$line" in
${uniquetag}*) printf "%s\n" "$line" | tee -a out_AND_err.file | sed -e "s/^${uniquetag}//" >> out.file ;;
*) printf "%s\n" "$line" >> out_AND_err.file ;;
esac;
done;
# see the results:
grep "^" out.file out_AND_err.file
ls unknown
) untuk mencetak sesuatu di stderr? >&2 echo "error"
akan baik-baik saja. (2) tee
dapat menambahkan beberapa file sekaligus. (3) Mengapa tidak hanya cat
bukan grep "^"
? (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
cmd 2>>file-err | tee -a file1 >>file2
cat file-err >> file1
rm file-err
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:
... | tee file1 file2
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:
... | tee -a file1 >>file2
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).
sponge
halnya:(cmd | tee -a out >> out+err) 2>&1 | sponge >> out+err
Untuk kepentingan keragaman:
Jika sistem Anda mendukung /dev/stderr
, maka
(cmd | tee -a /dev/stderr) 2>> file1 >> file2
akan bekerja. Output standar dari cmd
dikirim ke stdout dan stderr dari pipa. Kesalahan standar cmd
memotong tee
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.
out+err
danout
maksud di sini. Nama file? Streaming akan diarahkan?