Hem stdout hem de stderr'i bash içinde borulama?


156

Bash'ın daha yeni sürümlerinde, &>(doğru anlarsam), hem stdout hem de stderr'i bir dosyaya ( &>>Adrian'ın açıkladığı gibi dosyaya ekler ) yönlendiren operatöre sahip gibi görünüyor .

Aynı şeyi elde etmenin en basit yolu nedir, bunun yerine başka bir komuta geçmek mi?

Örneğin, bu satırda:

cmd-doesnt-respect-difference-between-stdout-and-stderr | grep -i SomeError

Grep'in hem stdout hem de stderr'deki içerikle eşleşmesini istiyorum (etkili bir şekilde onları tek bir akışta birleştirin).

Not : Bu soru, yönlendirmeyi değil , boru tesisatını soruyor - bu nedenle şu anda bir kopyası olarak işaretlenen sorunun bir kopyası değil.


Hem stdout hem de stderr'i doğru şekilde borulamak için bağlı sorudaki ikinci cevaba ( stackoverflow.com/a/637834/1129642 ) bakın . Başka soruya gerek yok.
Marki555

4
@triplee Tam bir kopya değil, değil mi? Pipo dosyaya yönlendirme mi?
Benjamin W.

@BenjaminW Kabul edilen cevap olmasa da, her iki senaryoyu da çözen en az bir cevap var. Bu oldukça yaygın bir sorudur, bu yüzden muhtemelen daha iyi bir kopya bulabiliriz veya bir moderatörden bunları birleştirmesini isteyebiliriz - hatta en kötü durumda, bu konu için tamamen yeni bir kanonik hazırlayabiliriz. Daha iyi bir dupe bulursanız, kesinlikle önerin. Şimdiden teşekkürler.
tripleee

12
@tripleee, Evet, ama cevapların hiçbiri |&"hem stdout hem de stderr bir boruya yönlendirmek" için en uygun çözüm olduğunu düşünüyorum kısayolu kullanın .
Benjamin W.

3
Bu, bağlantılı sorunun bir kopyası değil ve Marko'nun cevabının istediğimi yaptığı açık değildi. Ayrıca, | &. Yeniden açmak için oylama.
Martin Bonner Monica'yı

Yanıtlar:


163

( Bir dosyaya daha önce var olan bir dosyayı yeniden yönlendirip üzerine &>>file yazacağını unutmayın .)&>

Birleştirmek stdoutve stderrikincisini kullanarak önceki yönlendirirsiniz 2>&1. Bu, stderr'ı (dosya tanımlayıcı 2) stdout'a (dosya tanımlayıcı 1) yönlendirir, örn:

$ { echo "stdout"; echo "stderr" 1>&2; } | grep -v std
stderr
$

stdoutstdout'a stderrgider, stderr'a gider. grepsadece görür stdout, böylece stderrterminale yazdırır.

Diğer yandan:

$ { echo "stdout"; echo "stderr" 1>&2; } 2>&1 | grep -v std
$

Hem stdout hem de stderr'e yazdıktan sonra, 2>&1stderr'ı stdout'a geri yönlendirir ve grepher iki dizeyi stdin'de görür, böylece her ikisini de filtreler.

Yeniden yönlendirme hakkında daha fazla bilgiyi buradan edinebilirsiniz .

Örneğinizle ilgili (POSIX):

cmd-doesnt-respect-difference-between-stdout-and-stderr 2>&1 | grep -i SomeError

veya şunu kullanarak >=bash-4:

cmd-doesnt-respect-difference-between-stdout-and-stderr |& grep -i SomeError

Konusundaki açıklama için teşekkürler &>>. Sorumu düzelttim.
Andrew Ferrier

18
Verilen örneklerime dayanarak açıkça görülmemesi durumunda örneğimi yanıtıma ekledim. Yan not olarak, |&yerine bash'a özgü de kullanabilirsiniz 2>&1 |.
Adrian Frühwirth

13
|&Gelecekteki okuyucular için @ AdrianFrühwirth tarafından önerilen kısayol hakkında yan not : Bu özellik yalnızca bashsürüm 4 ve üstü ile desteklenir . 3 veya daha düşük bir değer kullanıyorsanız, sadık kalmanız gerekir 2>&1 |.
tomocafe

3
Bash yönlendirme burada çok iyi açıklanmıştır . @ AdrianFrühwirth iyi bir iş çıkardı, yapıştırılan bağlantı daha da ileri gidiyor. Bazen, resmi Bash belgelerinin bu kadar iyi olmasını dilerdim.
David Andreoletti

112

Bash için bir kısaltma sahiptir 2>&1 |, yani, |&stdout'u ve stderr hem (bakınız boru, el ):

cmd-doesnt-respect-difference-between-stdout-and-stderr |& grep -i SomeError

Bu Bash 4.0'da tanıtıldı, sürüm notlarına bakın .


Bunu eksiksizlik için eklediğiniz için teşekkür ederiz. Birçok kişi hala bash 4.0 öncesi kullandığından diğer yanıtı doğru tutacağım. Ancak bu faydalıdır.
Andrew Ferrier

9
En önemlisi, macOS'ta gönderilen Bash bunu destekleyemeyecek kadar eskidir.
Ocak'ta Flimm

@Flimm ama zsh değil
Trenton

1
Ksh | & coproc için kullandığı için, bu gereksiz bir steno için kötü bir seçim gibi görünüyor. Bir sonraki adam kadar dups ve yönlendirmeler yığını olan satırları görmekten nefret ediyorum, ancak açık olduğu için söylenecek bir şey var .... ve bu yorumun çok fazla eklemediği için özür dilerim. Ben sadece yararlı bir cevap indirmeden steno için tatsızlık ifade etmek istedim, çünkü insanlar bunu görmek güzel. Bunu bilmiyordum, bu yüzden beni bilgilendirdiğin için teşekkürler.
Paul Hodges

@PaulHodges Taşınabilir olmadığına katılıyorum - çok fazla yazmamak için etkileşimli Bash oturumlarında kullanmayı seviyorum.
Benjamin W.
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.