2> & 1> output.log ve 2> & 1 arasındaki fark | tee çıktısı.log


35

Aşağıdaki iki komut arasındaki farkı bilmek istedim.

2>&1 > output.log 

ve

2>&1 | tee output.log

İş arkadaşlarımdan birinin yönlendirmek için ikinci seçeneği kullandığını gördüm. 2> & 1 'in ne yaptığını biliyorum, tek sorum, basit bir yönlendirme ">" işlecinin kullanılabileceği tee kullanmanın amacı nedir?

Yanıtlar:


11

İki komuta ayrı ayrı bakmak:

utility 2>&1 >output.log 

Burada, yeniden yönlendirmeler soldan sağa işlendiğinden, standart hata akışı önce standart çıktı akışının gittiği her yere (muhtemelen konsola) yönlendirilir ve ardından standart çıktı akışı bir dosyaya yönlendirilir. Standart hata akımı olur değil o dosyaya yönlendirilebilir.

Bunun gözle görülür etkisi, ekranda standart hata ile üretilenleri ve dosyada standart çıktıyla üretilenleri elde etmeniz olabilir.

utility 2>&1 | tee output.log

Burada standart hatayı standart çıkış akımıyla aynı yere yönlendirirsiniz. Bu, her iki akımın da işletime teetek bir iç içe çıkış akışı olarak aktarılacağı ve bu standart çıktı verilerinin verilen dosyaya kaydedileceği anlamına gelir tee. Veriler ayrıca teekonsolda da çoğaltılacaktır (bu, teeveri akışlarını çoğaltır).

Bunlardan hangisinin kullanıldığı, hangisine ulaşmak istediğinizi temel alır.

İkinci boru hattının etkisini sadece >(örneğin utility >output.log 2>&1standart çıktı ve hatayı dosyaya kaydedecek şekilde) ile yeniden oluşturamayacağınızı unutmayın. teeVerileri konsolda ve çıktı dosyasında almak için kullanmanız gerekir .


Ek Notlar:

Görünür birinci komut etkisi

utility 2>&1 >output.log 

aynı olurdu

utility >output.log

Yani standart çıktı dosyaya gider ve standart hata konsola gider.

Yukarıdaki komutların her birinin sonuna başka bir işlem adımı eklenmiş olsaydı, olsa büyük bir fark olurdu:

utility 2>&1 >output.log | more_stuff

utility >output.log      | more_stuff

İlk boru hattında, standart girdi verisi olarak more_stuffstandart hata akışı olanı utilityalırken, ikinci boru hattında, sadece bir boruya gönderilen standart çıktı akımı olduğundan, boru more_stuffhattının parçası hiçbir şey alamazdı. Standart girişinde okumak için.


Komutuyla 'ile utility 2>&1 | tee output.logdosyaya yazıldığı gibi, 1 olarak beri 2 de olduğu, tee yönlendirilir ediliyor söylemek demek. Tee akışını çoğaltır yana, çıktı hem? De konsolda görüntülenir arasındaki Dolayısıyla fark utility 2>&1 > output.logve utility 2>&1 | tee output.logolduğunu teeo akışını çoğaltır doğru olacağını söyledi.?
motive

Ve örnekleri utility 2>&1 > output.log | more_stuffile utility >ouput.log| more_stuff , is the difference that more_stuff`, konsola giriş olarak standart hata çıktısına sahip more_stuffmi? İkinci örnekte, konsola çıkış olmadığından, esas olarak giriş yapılmadı.more_stuff mu? Evetse, önceki paragraftan bu yana net değil, standart çıktının dosyaya gittiğini ve standart hatanın konsola gittiğini unutmayın.
Motive

@Motivated İlk yorumunuz bana doğru geliyor, evet. İkinci yoruma gelince: İlk komutta, başlangıçta hata akışına gönderilen (ancak standart çıkışa yönlendirilen) bir mesaj more_stuffalacaktı . Orada olmasaydı konsola çıkacağı için değil, standart çıkış akışına gideceği için değil . İkinci komutta, boru hattının sol tarafından standart bir çıktı olmadığından hiçbir şey almaz . 2. komuttaki hata akışı hala konsolda kalır. utilitymore_stuffmore_stuffutility
Kusalananda

Teşekkürler. Bunu demek istiyorsun çünkü komututility > output.log | more_stuff standart çıkış akışında standart bir hata bakış açısıyla bir çıktıya yol açmadığı ?
Motive

@ Motive Edildi Sol taraf standart çıktıda hiçbir şey üretmediğinden (yönlendirilir), boru üzerinden veri gönderilmez.
Kusalananda

24

Editoryal not

Lütfen bu cevap hakkındaki yorumları mutlaka okuyun - derobert .


Orijinal cevap

2>&1 >output.logaraçlar ilk dosya sap 1 (standart çıktı) tüm dosya tanıtıcısı 2 şeyler (standart hata) göndermeye başlamak daha sonra dosyaya olduğunu göndermek output.log. Başka bir deyişle, günlük hataya standart hata ve standart çıktı gönderir.

2>&1 | tee output.log2>&1bit ile aynıdır , standart çıktı ve standart hatayı standart çıktı akışında birleştirir. Daha sonra boru bu aracılığıyla tee(gibi standart çıkışa Standart girişini gönderecek programı cat) ve ayrıca dosyaya. Böylece iki akışı birleştirir (hata ve çıktı), sonra bunu terminale ve dosyaya verir.

Alt satırda, ilk önce dosyaya stderr/ stdoutgönderilirken, ikincisi onu hem dosyaya hem de standart çıktısına gönderir (ikincisi , standart çıktısını yeniden yönlendiren başka bir yapının içinde olmadıkça muhtemelen terminaldir).

Son ihtimalden bahsediyorum çünkü şöyle şeyler olabilir:

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

terminalde hiçbir şeyin bitmediği yer.


13
-1 Sözdizim hakkınız var, ancak anlambiliminiz yok. Çalıştır cat /doesnotexist 2>&1 >output.txt- cat: /doesnotexist: No such file or directoryterminalde görüntülendiğini göreceksiniz ve output.txt boş bir dosya. Öncelik ve kapanış sırası oyunda: 2>&1( geçerli fd1'den dup fd2), sonra >output.txt(fd1'i output.txt dosyasına yönlendir, başka bir şeyi değiştirmeden). Farklı olmasının nedeni 2>&1 |öncelik sırasıdır: |önceden >.
Arcege

5
Bu cevap aslında her bakımdan temelde yanlıştır . Aşağıdaki cevapların birçoğu daha iyi, ama bence Kusalananda'nın en açık olanı .
Michael Homer

2
@ user14408: Hiç Unix ve Linux'ta bir hesap oluşturup bu cevabı talep ediyorsanız, lütfen yorumları ele aldıktan sonra editoryal notumu kaldırmaktan çekinmeyin.
derobert

8

İlk komut başka bir görevi yerine getirecektir:

Sonra

2>&1 > output.log 

eski STDOUT, STDERR'ye kaydedilecek (kopyalanacak) ve daha sonra STDOUT dosyaya yönlendirilecek.

Böylece stdout dosyaya gidecek ve stderr konsola gidecektir.

Ve

 2>&1 | tee output.log

her iki akış da tee'ye yönlendirilir. Tee herhangi bir girişi stdout'una (sizin durumunuzdaki konsol) ve dosyaya kopyalayacaktır (output.log ) .

Ve başka bir ilk şekli daha var:

    > output.log  2>&1

bu, hem STDOUT'u hem de STDERR'yi dosyaya yönlendirecektir.


4

Eski çıktı sadece dosyaya verilir. İkinci hem dosyaya verir ve ekrana.


4

Bunun nedeni 2>&1 | tee, stdout ve stderr'yi bir günlük dosyasına yakalayabilmek ve aynı anda ekranda görebilmek. Bu da yapılabilir >output.txt 2>&1 & tail -f, ancak arka plandaki komutun ne zaman sonlandırılacağını bilemezsiniz - program sonlandırılıyor ya da çıktısız çalışıyor mu? 2>&1 | teeProgramcılar için ortak bir deyim oldu.


Örneğin, 2> & 1> file.txt dosyasının hem stdout'u hem de stderr'yi file.txt dosyasına yakalamayacağını mı demek istiyorsunuz?
Motive

0

Önce bazı örnek kodları görelim:

#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");
}

Sonuçları karşılaştıralım:
./helloerror
+ dosya: mesaj yok; konsol: mesaj 1,2,3;

./helloerror >error.txt
+ dosya: mesaj 1,2; konsol: mesaj 3;

./helloerror 2>&1 >error.txt
+ dosya: mesaj 1,2; konsol: mesaj 3;
+ ./helloerror ile aynı> error.txt

./helloerror >error.txt 2>&1
+ dosya: mesaj 3,1,2; konsol: mesaj yok;
+ 3, önce 1, sonra 2 sırasına dikkat edin

./helloerror | tee error.txt 2>&1
+ dosya: mesaj 1,2; konsol: mesaj 3,1,2;
+ 3, önce 1, sonra 2 sırasına dikkat edin

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

Kullanmak için:
./helloerror >error.txt 2>&1
-> biri dosyadaki tüm (stdout + stderr) mesajlarını istiyor ancak konsolda tutturulmamışsa

./helloerror 2>&1 | tee error.txt
-> biri dosyadaki tüm (stdout + stderr) mesajlarını istiyorsa ve konsolda basılıysa


-1

İşte Unix çıktı akışlarını özetleyen bir yazı: http://www.devcodenote.com/2015/04/unix-output-streams.html

Yayından bir pasaj:

3 standart çıkış akışı vardır:

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.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.