İki adlandırılmış boruyu linux'taki tek giriş akışına nasıl bağlarım?


64

|Linux'ta pipes ( ) özelliğini kullanarak standart girdiyi bir veya birkaç çıktı akışına iletebilirim.

teeAlt işlemleri ayırmak için çıktıyı bölmek için kullanabilirim .

İki giriş akışına katılmak için bir komut var mı?

Bu konuda nasıl giderim? Diff nasıl çalışır?

Yanıtlar:


105

Şahsen, favorim (çoğu Linux dağıtımında standart olan bash ve diğer şeyleri gerektirir)

Detaylar, iki şeyin ne çıktığına ve onları nasıl birleştirmek istediğinize bağlı olarak değişebilir ...

Komut1 ve komut2'nin içeriği birbiri ardına çıktı:

cat <(command1) <(command2) > outputfile

Ya da her iki komut da yan yana görmek istediğiniz aynı verinin alternatif versiyonlarını verirse (bunu snmpwalk ile kullandım; diğer taraftaki sayılar ve diğer taraftaki MIB adları):

paste <(command1) <(command2) > outputfile

Veya iki benzer komutun çıktısını karşılaştırmak istiyorsanız (iki farklı dizinde bir bulma söyleyin)

diff <(command1) <(command2) > outputfile

Veya bir tür çıktılar sipariş ettikleri takdirde, bunları birleştirin:

sort -m <(command1) <(command2) > outputfile

Veya her iki komutu bir seferde çalıştırın (bazı şeyleri biraz karıştırmak olabilir):

cat <(command1 & command2) > outputfile

<() Operatörü, her komut için adlandırılmış bir boru (veya / dev / fd) kurar, bu komutun çıktısını adlandırılmış boruya (veya / dev / fd filehandle referansı) geçirir ve adı komut satırına geçirir. > () İle eşdeğer var. Sen yapabilirdi: command0 | tee >(command1) >(command2) >(command3) | command4aynı anda örneğin 4 diğer komutlara bir komutun çıktısının göndermek.


müthiş! bash'ın manpage'ini çok fazla okudum, ama bunu seçmedim
Javier,

2
Referansı [ileri bash komut dosyası kılavuzu] 'da ( tldp.org/LDP/abs/html/process-sub.html ) linux dokümantasyon projesinde bulabilirsiniz
brice

3
i içinden borularla serpiştirilmiş çizgileri önlemek başardı grep --line-bufferedeşzamanlı için kullanışlı - grep'ing tailbirden fazla günlük dosyalarının. bkz. stackoverflow.com/questions/10443704/line-buffered-cat
RubyTuesdayDONO

16

catGoril gösterdiği gibi, iki buhar diğerine ekleyebilirsiniz .

Ayrıca bir FIFO oluşturabilir, komutların çıktısını buna yönlendirebilir, ardından başka bir programla FIFO'dan okuyabilirsiniz:

mkfifo ~/my_fifo
command1 > ~/my_fifo &
command2 > ~/my_fifo &
command3 < ~/my_fifo

Özellikle yalnızca dosya yazacak veya okuyacak programlar veya yalnızca stdout / dosya çıkaran programları yalnızca diğerini destekleyen programlarla karıştırmak için kullanışlıdır.


2
Bu, pfSense (FreeBSD) üzerinde çalışır, oysa kabul edilen cevap değildir. Teşekkür ederim!
Nathan,

9
(tail -f /tmp/p1 & tail -f /tmp/p2 ) | cat > /tmp/output

/tmp/p1ve /tmp/p2girdi borularınız, /tmp/outputçıktı ise.


6
Yan her iki komutları sürece: Not ()... her satır (ve bölünmezlik için diğer bazı belirsiz POSIX kuralları) floş bunların çıkışları, bazı garip kedi girişine çabalıyorlar ile bitebileceğini
Freiheit

Ve işareti karakteri yerine noktalı virgül kullanmamalısınız?
Samir,

Bu Epik şeyler
Mobigital

5

Bunun için özel bir program hazırladım: fdlinecombine

Birden fazla boru okur (genellikle program çıktılarını gösterir) ve bunları sıralı olarak stdout'a yazar.


Reklamı olarak çalışır. Halka açık hale getirdiğiniz için teşekkürler.
alexei

3

Bunun için kullandığım gerçekten harika bir komut tpipe, bu kadar yaygın olmadığı için derlemeniz gerekebilir. Tam olarak neden bahsettiğinizi yapmak için gerçekten harika ve o kadar temiz ki genellikle yüklüyorum. Man sayfası http://linux.die.net/man/1/tpipe adresinde bulunur . Şu anda listelenen indirme bu arşivde yer almaktadır http://www.eurogaran.com/downloads/tpipe/ .

Bu böyle kullanılır.

## Reinject sub-pipeline stdout into standard output:
$ pipeline1 | tpipe "pipeline2" | pipeline3

3

Burada dikkatli ol; sadece onları yakalamak, sonuçları isteyip istemediğiniz şekilde karıştırmakla sonuçlanacaktır: örneğin, eğer günlük dosyalarıysa, muhtemelen bir yarısından bir satırdan diğerine bir satır istemezsiniz. Eğer sorun değilse, o zaman

kuyruk-f / tmp / p1 / tmp / p2> / tmp / çıkış

çalışacak. Bu doğru değilse , o zaman satır tamponlama yapacak ve sadece tam satırları çıkaran bir şey bulmanız gerekecektir. Syslog bunu yapar, ama başka ne olabilir emin değilim.

EDIT: tamponlanmamış okuma ve adlandırılmış yöneltmeler için en uygun hale getirme:

/ tmp / p1, / ​​tmp / p2, / tmp / p3 adlı, "mkfifo / tmp / p N " tarafından oluşturulmuş

kuyruk -q -f / tmp / p1 / tmp / p2 | awk '{$ 0 yazdır>> "/ tmp / p3"; Kapat ( "/ tmp / p3"); fflush ();} '&

Şimdi bu şekilde, "/ tmp / p3" pipe isimli Çıktıyı tamponsuz olarak okuyabiliriz :

kuyruk-f / tmp / p3

sıralamada küçük bir hata var, ilk girdi borusunu / tmp / p1'i "başlatmanız" gerekiyor:

echo -n> / tmp / p1

Kuyruğu açmak için ilk önce 2. boru / tmp / p2'den gelen girdiyi kabul edecek ve / tmp / p1'e gelene kadar bekleymeyiniz. bu durumda olmayabilir, eğer eminseniz / tmp / p1 önce girdiyi alır.

Ayrıca kuyruğa girmek için -q seçeneği gerekir, dosya isimleri hakkında çöp yazdırmaz.


daha yararlı olacaktır: "tail -q -f / tmp / p1 / tmp / p2 | another_command" , satır satır yapılacak ve -q seçeneği ile başka bir çöp
basmayacaktır

tamponsuz dosya / adlandırılmış kanal kullanımı için: tail -q -f /tmp/p1 /tmp/p2 | awk '{print $0 > "/tmp/p3"; close("/tmp/p3"); fflush();}' & şimdi / tmp / p3 bile boru adlandırılabilir ve sadece bunu okuyabilir tail -f /tmp/p3tüm bu olup = satır satır tamponsuz ancak tür küçük hata yoktur. Kuyruğun 2. çıktıyı kabul etmesi için 1. dosya / adlandırılmış borunun ilk başlatılması gerekir. bu yüzden ihtiyacınız olacak echo -n > /tmp/p1ve her şey daha sorunsuz çalışacak.
readyblue

1

Bunu yapmak için en iyi program lmerge. Freihart'ın cevabından farklı olarak, satır yönelimlidir, böylece iki komutun çıktısı birbirine zarar vermez. Diğer çözümlerden farklı olarak girdiyi oldukça birleştirir, böylece hiçbir komut çıktıya hakim olamaz. Örneğin:

$ lmerge <(yes foo) <(yes bar) | head -n 4

Çıktısını verir:

foo
bar
foo
bar
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.