Dalam bash, panggilan foo
akan menampilkan output apa pun dari perintah itu di stdout.
Memanggil foo > output
akan mengarahkan output apa pun dari perintah itu ke file yang ditentukan (dalam hal ini 'keluaran').
Apakah ada cara untuk mengarahkan output ke file dan menampilkannya di stdout?
foo > output
data yang ditulis ke stdout dan stdout adalah file bernamaoutput
. Artinya, menulis ke file adalah menulis ke stdout. Anda bertanya apakah mungkin untuk menulis ke stdout dan ke terminal.Jawaban:
Perintah yang Anda inginkan bernama
tee
:Misalnya, jika Anda hanya peduli dengan stdout:
Jika Anda ingin memasukkan stderr, lakukan:
2>&1
mengalihkan saluran 2 (stderr / standard error) ke saluran 1 (stdout / output standar), sehingga keduanya ditulis sebagai stdout. Ini juga diarahkan ke file output yang diberikan padatee
perintah.Selanjutnya, jika Anda ingin menambahkan file log, gunakan
tee -a
sebagai:sumber
-a
argumentee
untuk menambahkan kontenoutput.file
, alih-alih menimpanya:ls -lR / | tee -a output.file
$?
setelah itu akan mengembalikan kode statustee
, yang mungkin bukan yang Anda inginkan. Sebagai gantinya, Anda bisa menggunakannya${PIPESTATUS[0]}
.2>&1
membuang aliran stderr dan stdout.tee outfile
mengambil aliran yang didapatnya dan menulisnya ke layar dan ke file "outfile".Ini mungkin yang dicari kebanyakan orang. Situasi yang mungkin terjadi adalah beberapa program atau skrip bekerja keras untuk waktu yang lama dan menghasilkan banyak output. Pengguna ingin memeriksanya secara berkala untuk mengetahui perkembangannya, tetapi juga ingin keluarannya ditulis ke file.
Masalahnya (terutama ketika mencampur aliran stdout dan stderr) adalah bahwa ada ketergantungan pada aliran yang disiram oleh program. Jika, misalnya, semua menulis ke stdout yang tidak memerah, tapi semua menulis ke stderr yang memerah, maka mereka akan berakhir keluar dari urutan kronologis dalam file output dan pada layar.
Ini juga buruk jika program hanya menghasilkan 1 atau 2 baris setiap beberapa menit untuk melaporkan kemajuan. Dalam kasus seperti itu, jika output tidak memerah oleh program, pengguna bahkan tidak akan melihat output di layar selama berjam-jam, karena tidak ada yang akan didorong melalui pipa selama berjam-jam.
Pembaruan: Program
unbuffer
, bagian dariexpect
paket, akan menyelesaikan masalah buffering. Ini akan menyebabkan stdout dan stderr untuk menulis ke layar dan file segera dan tetap sinkron ketika digabungkan dan dialihkan ketee
. Misalnya:sumber
$ stdbuf -o 0 program [arguments...] 2>&1 | tee outfile
python
memiliki opsi-u
bawaan yang membatalkan keluaran.Cara lain yang bekerja untuk saya adalah,
seperti yang ditunjukkan pada manual bash gnu
Contoh:
Untuk informasi lebih lanjut, lihat pengalihan
sumber
$?
setelah itu akan mengembalikan kode statustee
, yang mungkin bukan yang Anda inginkan. Sebagai gantinya, Anda bisa menggunakannya${PIPESTATUS[0]}
.Anda terutama dapat menggunakan solusi Zoredache , tetapi Jika Anda tidak ingin menimpa file output, Anda harus menulis tee dengan opsi -a sebagai berikut:
sumber
Sesuatu untuk ditambahkan ...
Paket unbuffer memiliki masalah dukungan dengan beberapa paket di bawah fedora dan redhat rilis unix.
Mengesampingkan masalah
Mengikuti berhasil bagi saya
sumber
Penggunaan
tail -f output
harus berhasil.sumber
Jawaban bonus karena penggunaan ini membawa saya ke sini:
Dalam kasus di mana Anda perlu melakukan ini sebagai pengguna lain
Perhatikan bahwa gema akan terjadi saat Anda dan penulisan file akan terjadi sebagai "some_user" yang TIDAK akan berfungsi adalah jika Anda menjalankan gema sebagai "some_user" dan mengarahkan ulang output dengan >> "some_file" karena pengalihan file akan terjadi seperti kamu.
Petunjuk: tee juga mendukung append dengan flag -a, jika Anda perlu mengganti baris dalam file sebagai pengguna lain Anda bisa mengeksekusi sed sebagai pengguna yang diinginkan.
sumber
< command > |& tee filename
# ini akan membuat file "nama file" dengan status perintah sebagai konten, Jika file sudah ada akan menghapus konten yang ada dan menulis status perintah.< command > | tee >> filename
# ini akan menambahkan status ke file tetapi tidak mencetak status perintah pada standard_output (layar).Saya ingin mencetak sesuatu dengan menggunakan "echo" di layar dan menambahkan data yang di-echo ke file
sumber
Anda dapat melakukannya untuk seluruh skrip Anda dengan menggunakan sesuatu seperti itu di awal skrip Anda:
Ini mengarahkan output stderr dan stdout ke file yang dipanggil
mylogfile
dan membiarkan semuanya masuk ke stdout pada saat yang sama .Ini digunakan beberapa trik bodoh:
exec
tanpa perintah untuk mengatur pengalihan,tee
untuk menduplikasi output,NUL
karakter sederhana yang ditentukan oleh$'string'
notasi bash khusus) untuk menentukan bahwa skrip dimulai kembali (tidak ada parameter setara dapat digunakan oleh karya asli Anda),pipefail
opsi.Jelek tetapi bermanfaat bagi saya dalam situasi tertentu.
sumber
tee sempurna untuk ini, tetapi ini juga akan melakukan pekerjaan
sumber
;
, output akan jauh tertunda selama perintah lambat.