Perbedaan antara 2> & 1> output.log dan 2> & 1 | tee output.log

35

Saya ingin tahu perbedaan antara dua perintah berikut

2>&1 > output.log 

dan

2>&1 | tee output.log

Saya melihat salah satu kolega saya menggunakan opsi kedua untuk mengarahkan ulang. Saya tahu apa yang dilakukan 2> & 1, satu-satunya pertanyaan saya adalah apa tujuan menggunakan tee di mana operator pengalihan ">" sederhana dapat digunakan?

Chander Shivdasani
sumber

Jawaban:

11

Melihat kedua perintah secara terpisah:

utility 2>&1 >output.log 

Di sini, karena pengalihan diproses dengan cara dari kiri ke kanan, aliran kesalahan standar pertama-tama akan dialihkan ke mana pun aliran keluaran standar mengalir (mungkin ke konsol), dan kemudian arus keluaran standar akan dialihkan ke file. Aliran kesalahan standar tidak akan diarahkan ke file itu.

Efek yang terlihat dari ini adalah Anda mendapatkan apa yang diproduksi pada kesalahan standar di layar dan apa yang diproduksi pada output standar dalam file.

utility 2>&1 | tee output.log

Di sini, Anda mengarahkan kesalahan standar ke tempat yang sama dengan aliran output standar. Ini berarti bahwa kedua aliran akan disalurkan ke teeutilitas sebagai aliran keluaran tunggal yang saling terkait, dan bahwa data keluaran standar ini akan disimpan ke file yang diberikan oleh tee. Selain itu data akan direproduksi teedi dalam konsol (ini yang teedilakukan, itu menggandakan aliran data).

Yang mana salah satunya digunakan tergantung pada apa yang ingin Anda capai.

Perhatikan bahwa Anda tidak akan dapat mereproduksi efek dari pipa kedua dengan adil >(seperti pada utility >output.log 2>&1, yang akan menghemat keluaran standar dan kesalahan dalam file). Anda perlu menggunakan teeuntuk mendapatkan data di konsol serta di file output.


Catatan tambahan:

The terlihat efek dari perintah pertama,

utility 2>&1 >output.log 

akan sama dengan

utility >output.log

Yaitu, output standar pergi ke file dan kesalahan standar pergi ke konsol.

Jika langkah pemrosesan lebih lanjut ditambahkan ke akhir dari masing-masing perintah di atas, akan ada perbedaan besar:

utility 2>&1 >output.log | more_stuff

utility >output.log      | more_stuff

Pada pipa pertama, more_stuffakan mendapatkan apa yang awalnya merupakan aliran kesalahan standar utilitysebagai data input standarnya, sedangkan pada pipa kedua, karena hanya aliran keluaran standar yang dihasilkan yang dikirim melalui pipa, more_stuffbagian dari pipa tidak akan mendapatkan apa-apa untuk membaca input standarnya.

Kusalananda
sumber
Dengan perintah " utility 2>&1 | tee output.log, apakah Anda bermaksud mengatakan bahwa karena 1 diarahkan ke tee, 2 juga. Karena tee menduplikasi aliran, output ditampilkan pada konsol serta ditulis ke file? Karena itu perbedaan antara utility 2>&1 > output.logdan utility 2>&1 | tee output.logada teedi dalamnya duplikat aliran. Apakah itu benar?
Dimotivasi
Dengan contoh utility 2>&1 > output.log | more_stuffdan utility >ouput.log| more_stuff , is the difference that more_stuff` memiliki output kesalahan standar ke konsol sebagai input more_stuff? Karena pada contoh kedua, tidak ada output ke konsol, pada dasarnya tidak ada input more_stuff? Jika ya, itu tidak jelas karena paragraf sebelumnya Anda mencatat bahwa output standar pergi ke file dan kesalahan standar pergi ke konsol.
Termotivasi
@Motivasi Komentar pertama Anda tampaknya benar bagi saya, ya. Adapun komentar kedua: Pada perintah pertama, more_stuffakan menerima apa yang utilityawalnya dikirim ke aliran kesalahannya (tetapi yang diarahkan ke output standar). Bukan karena itu akan berakhir di konsol jika more_stufftidak ada di sana, tetapi karena itu akan ke aliran output standar . Pada perintah kedua, tidakmore_stuff menerima apa - apa karena tidak ada output standar dari sisi kiri pipa. Aliran kesalahan dari utilitymasih akan berakhir di konsol di perintah ke-2.
Kusalananda
Terima kasih. Apakah maksud Anda karena perintah utility > output.log | more_stufftidak menghasilkan output dalam aliran output standar dari sudut pandang kesalahan standar?
Termotivasi
@ Dimotivasi Karena sisi kiri tidak menghasilkan apa pun pada output standar (dialihkan), tidak ada data akan dikirim melalui pipa.
Kusalananda
24

Catatan editorial

Pastikan untuk membaca komentar pada jawaban ini - derobert .


Jawaban asli

2>&1 >output.logberarti pertama mulai mengirim semua file menangani 2 hal (kesalahan standar) ke file menangani 1 (output standar) kemudian mengirimkannya ke file output.log. Dengan kata lain, kirim kesalahan standar dan output standar ke file log.

2>&1 | tee output.logsama dengan 2>&1bit, ia menggabungkan keluaran standar dan kesalahan standar ke aliran keluaran standar. Kemudian pipa itu melalui teeprogram yang akan mengirim input standar ke output standar (seperti cat) dan juga ke file. Jadi ia menggabungkan dua aliran (kesalahan dan keluaran), kemudian mengeluarkannya ke terminal dan file.

Intinya adalah bahwa yang pertama mengirimkan stderr/ stdoutke file tersebut, sedangkan yang kedua mengirimkannya ke kedua file dan output standar (yang mungkin terminal kecuali Anda berada di dalam konstruk lain yang telah diarahkan output standar).

Saya menyebutkan kemungkinan terakhir karena Anda dapat memiliki hal-hal seperti:

(echo hello | tee xyzzy.txt) >plugh.txt

di mana tidak ada yang berakhir di terminal.

derobert
sumber
13
-1 Anda memiliki hak sintaksis, tetapi tidak semantik. Jalankan cat /doesnotexist 2>&1 >output.txt- Anda akan melihat lihat cat: /doesnotexist: No such file or directoryditampilkan ke terminal dan output.txt adalah file kosong. Urutan prioritas dan penutupan sedang dimainkan: 2>&1(dup fd2 dari fd1 saat ini ), kemudian >output.txt(redirect fd1 ke output.txt, tidak mengubah apa pun). Alasan yang 2>&1 |berbeda adalah karena urutan prioritas: |sebelumnya >.
Arcege
5
Jawaban ini pada dasarnya salah dalam hal yang mendasar . Banyak jawaban di bawah ini yang lebih baik, tetapi saya pikir yang satu ini oleh Kusalananda adalah yang paling jelas.
Michael Homer
2
@ user14408: Jika Anda pernah membuat akun di Unix & Linux dan mengklaim jawaban ini, silakan menghapus catatan editorial saya setelah Anda menanggapi komentar.
derobert
8

Perintah pertama akan melakukan tugas lain:

Setelah

2>&1 > output.log 

STDOUT yang lama akan disimpan (disalin) di STDERR dan kemudian STDOUT akan diarahkan ke file.

Jadi, stdout akan masuk ke file dan stderr akan pergi ke konsol.

Dan masuk

 2>&1 | tee output.log

kedua aliran akan dialihkan ke tee. Tee akan menduplikasi input apa pun ke stdout-nya (konsol dalam kasus Anda) dan ke file ( output.log).

Dan ada bentuk lain dari yang pertama:

    > output.log  2>&1

ini akan mengarahkan STDOUT dan STDERR ke file.

osgx
sumber
4

Mantan output hanya ke file. Output kedua baik ke file dan ke layar.


sumber
4

Alasannya 2>&1 | teeadalah untuk dapat menangkap stdout dan stderr ke file log dan melihatnya di layar secara bersamaan. Ini bisa dilakukan >output.txt 2>&1 & tail -fjuga, tetapi Anda tidak akan tahu kapan perintah latar belakang diakhiri - apakah program dihentikan atau apakah program itu berjalan tanpa output. Itu 2>&1 | teeadalah ungkapan umum untuk para programmer.

Arcege
sumber
Apakah Anda bermaksud mengatakan bahwa 2> & 1> file.txt misalnya tidak akan menangkap stdout dan stderr ke file.txt?
Termotivasi
0

Mari kita lihat beberapa kode contoh terlebih dahulu:

#include <stdio.h>
main() 
{
// message 1, on stdout (using  printf)
printf("%s",          "message 1, on stdout (using  printf)\n");

// message 2, on stdout (using fprintf)
fprintf(stdout, "%s", "message 2, on stdout (using fprintf)\n");

// message 3, on stderr (using fprintf)
fprintf(stderr, "%s", "message 3, on stderr (using fprintf)\n");
}

Mari kita bandingkan hasilnya:
./helloerror
+ file: tidak ada pesan; konsol: pesan 1,2,3;

./helloerror >error.txt
+ file: pesan 1,2; konsol: pesan 3;

./helloerror 2>&1 >error.txt
+ file: pesan 1,2; konsol: pesan 3;
+ sama dengan ./helloerror> error.txt

./helloerror >error.txt 2>&1
+ file: pesan 3,1,2; konsol: tidak ada pesan;
+ perhatikan urutan 3 pertama, lalu 1, lalu 2

./helloerror | tee error.txt 2>&1
+ file: pesan 1,2; konsol: pesan 3,1,2;
+ perhatikan urutan 3 pertama, lalu 1, lalu 2

./helloerror 2>&1 | tee error.txt
+ file: pesan 3,1,2; konsol: pesan 3,1,2;

Untuk menggunakan:
./helloerror >error.txt 2>&1
-> jika seseorang ingin semua (stdout + stderr) pesan dalam file, tetapi tidak pinted pada konsol

./helloerror 2>&1 | tee error.txt
-> jika seseorang ingin semua (stdout + stderr) pesan dalam file dan dicetak pada konsol

Hari Perev
sumber
-1

Berikut ini adalah pos yang merangkum aliran keluaran Unix: http://www.devcodenote.com/2015/04/unix-output-streams.html

Cuplikan dari pos:

Ada 3 stream output standar:

STDIN - Standard Input - Writes from an input device to the program
STDOUT - Standard Output - Writes program output to screen unless specified otherwise.
STDERR - Standard Error Output - Writes error messages. Also printed to the screen unless specified otherwise.
Abhishek Jain
sumber