Boru stdout olmadan stderr boru nasıl


24

Standart çıkış akışını borulamadan standart hata akışını nasıl borularım?

Bu komutun işe yaradığını biliyorum ama aynı zamanda standardı da yazıyor.

Command 2>&1 | tee -a $LOG

Sadece standart hatayı nasıl alabilirim?

Not: Bundan istediğim sadece stderr akışını bir günlüğe yazmak ve konsola hem stderr hem de stdout yazmak.

Yanıtlar:


26

Bunu yapmak için, stderr ve stdout'u değiştirmek için bir ekstra dosya tanımlayıcısı kullanın:

find /var/log 3>&1 1>&2 2>&3 | tee foo.file

Temel olarak, işe yarıyor veya en azından çalıştığını düşünüyorum, şöyle:
Yeniden yönler soldan sağa değerlendirilir.

3>&1 Yeni bir dosya tanımlayıcı yapar, 3, fd 1'in (stdout) kopyası (kopya) olur.

1>&2 Stdout'u (1) bir fd 2 (stderr) kopyası yapın

2>&3 Fd 2'yi, daha önce stdout'un bir kopyası olan 3'ün bir kopyası (kopya) yapın.

Yani şimdi stderr ve stdout değiştirildi.

| tee foo.file tee, stderr içine yapılan dosya tanımlayıcısını 1 çoğaltır.


Oh, ksh ile test edilmemiş, ancak bash ile çalışıyor ...
Kyle Brandt

Teşekkürler, ksh da çalışır. Boru ve akarsu işlerinin çoğunun posix standardı olduğunu düşünüyorum.
C. Ross

"Kopyala" gerçekten doğru değil - Bkz. @ Guasqueño kullanıcısının yanıtı.
Kyle Brandt

Bu, aynı zamanda Windows tee.exeyüklü :) çalışır
Acorn

13

Kyle'ın Unix / Linux komutu, STDERR'yi STDOUT ile değiştirmeyi; ancak açıklama pek doğru değil. Yönlendirme operatörleri herhangi bir kopyalama veya kopyalama yapmazlar, sadece akışı farklı bir yöne yönlendirirler.

Kyle'ın komutunu 3> & 1'i geçici olarak hareket ettirerek yeniden yazmak, kavramı anlamayı kolaylaştırır:

find /var/log  1>&2  2>&3  3>&1  

Bu şekilde yazılmış olsa da, Linux bir hata gösterecektir çünkü & 3 henüz 3> & 1'den önce olduğu gibi mevcut değildir. 3> bir şey üçüncü bir boru kullanacağımızı ilan etmenin (tanımlamanın) bir yoludur, bu yüzden suya o boruya akmadan önce, örneğin Kyle'ın yazdığı şekilde yerleştirilmesi gerekir. Sadece eğlence için bu diğer yolu deneyin:

((echo "STD1";  anyerror "bbbb"; echo "STD2" ) 3>&1 4>&2 1>&4 2>&3) > newSTDOUT 2> newSTDERR

Kopya yapmanın bir yolu olmamak utanç verici. Aynı komutta "3> & 1 3> & 2" gibi şeyler yapamazsınız, çünkü Linux yalnızca birincisini kullanır ve ikinciyi reddeder.

(Henüz) hem hatayı hem de normal çıktısını bir dosyaya göndermenin bir yolunu bulamadım ve ayrıca bir komut ile hatanın bir kopyasını standart çıktıya gönderdim. Denemek için, her iki çıktının da (hata ve standart) bir günlük dosyasına gitmesini ve hatanın blackBerry'ime gönderilen bir e-posta iletisini göndermesini istiyorum. "Tee" kullanarak iki komutla yapabilirim ancak hata dosyadaki normal çıktı satırı arasında doğru sırada gösterilmiyor. Sorunu çözdüğümün çirkin yolu:

((echo "STD1"; sdfr "bbbb"; echo "STD2" ) 3>&1 1>&2 2>&3 | tee -a log1 ) 2>> log1

Log1'i iki kez kullanmam gerektiğini ve her iki durumda da, "tee" komutu için "-a" seçeneğini ve ikincisini ">>" kullanarak kullandığını belirtmeliyim.

Bir kedi günlüğü1 yaparak aşağıdakileri elde edersiniz:

STD1
STD2
-bash: sdfr: command not found

İkinci satırda hatanın olması gerektiği gibi görünmediğine dikkat edin.


Müthiş düzeltme!
Kyle Brandt

Bir FD'yi birden çok kez yönlendirebilmek için zsh ve mult_iosseçeneğe (varsayılan olarak açık) bakın.
Tom Hale

2

ksh (pdksh) için man sayfasına göre, sadece yapabilirsiniz:

Komut 2> & 1> / dev / null | kedi

yani stderr'den stdrr'e kopyalayın, stdreyi / dev / null dizinine yönlendirin, daha sonra 'cat -n' içine yönlendir

sistemimde pdksh üzerinde çalışıyor:

$ errorecho () {echo "$ @"> & 2;}

$ errorecho foo
foo

$ errorecho foo> / dev / null # hala stdout yönlendirilmiş olsa bile gösterilmeli
foo

$ errorecho foo 2> & 1> / dev / null | kedi
     1 foo
$   

BusyBox ile de çalışır
Udo G

1

İstediğin gibi çalışmasını sağladım çünkü ihtiyacım vardı ve emrini değiştirdim. şimdi benim için bu kullanarak debian sıkmak bash 3.2 kullanarak doğru çalışır

(echo "foo" 3>&1 1>&2 2>&3 | tee -a log1 ) 2>> log1 >> log2

log1, stdout ve stderr 'i günlüğe kaydederken, log2 sadece stderr' i günlüğe kaydeder ve ekrana koyduğu başka bir şey yoktur.

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.