Bir komutun çıktısını birden fazla komuta yönlendirmek mümkün müdür?


21

Bildiğim kadarıyla, standart çıktıyı ekrana ve diğer dosyalara bölmek için tee komutunu kullanabilirim:

command -option1 -option2 argument | tee file1 file2 file3 

Teorik olarak bir komut zinciri oluşturabilmem için çıktıyı tee kullanarak dosyalar yerine komutlara yönlendirmek mümkün müdür?


3
"Çıktı sinyali" ile ne demek istediğinizi açıklayın ve bir "komut ağı" oluşturarak ne demek istediğinizi açıklayın.
Janis

Linux'ta her komutun bir girişi ve iki çıkışı vardır. 0 (giriş için), 1 (çıkış için) ve 2 (hata çıkışı için) ile etiketlenirler. "Komut sinyali" derken 1'i düşünüyordum, çünkü tee komutunun yalnızca 1 etiketli çıktıyı paylaştığını okudum. "Komut ağı" derken çok teknik değildi; matematiksel bir bakış açısı, ancak basitçe tipolojik konuşan bir komut ağacını düşünüyordum, böylece bazı komutlar birden fazla çocuk komutunun ebeveyni olabilir.
Abdul Al Hazred

Açıklaman için teşekkürler. Unix'de özel bir anlamı olduğundan ve bu bağlamda terim çok yanıltıcı olduğundan, lütfen işaret kelimesini kullanmayın. Tekrar teşekkürler.
Janis

Komut satırında, UNIX ve Linux'ta bu anahtar kavramın özel anlamını öğrenmek için man -k sinyalini girin. Adam öldürmek başlamak için iyi bir sayfa olacaktır.
Rob

Ayrıca, birçok kişi stdin stdout ve stderr'yi giriş veya çıkış 'akışları' olarak adlandırır. Akış gibi küçük veri nehirleri var. Bunları toplu olarak tanımlamak için bir kelimeyle boğuşma konusunda haklıydınız, ancak sinyal yalnızca yanlış kelime.
Rob

Yanıtlar:


25

Komut satırında boruları ( http://linux.die.net/man/1/mkfifo ) kullanabilir teeve komutları adlandırılmış boruların üzerinde okuyabilirsiniz.

mkfifo /tmp/data0 /tmp/data1 /tmp/data2
cmd0 < /tmp/data0 & cmd1 < /tmp/data1 & cmd2 < /tmp/data2 &
command -option1 -option2 argument | tee /tmp/data0 /tmp/data1 /tmp/data2

İşlem commandbittiğinde, normalde işlemleri sonlandıracak teeher biri üzerinde bir EOF (0 bayt okunur) sinyali verecek olan adlandırılmış boruları kapatacaktır . Gerçek örnek:/tmp/dataNcmdN

$ mkfifo /tmp/data0 /tmp/data1 /tmp/data2
$ wc -l < /tmp/data0 & wc -w < /tmp/data1 & wc -c < /tmp/data2 &
$ tee /tmp/data0 /tmp/data1 /tmp/data2 < /etc/passwd >/dev/null
$ 61
1974
37

Arka plan işlemleri nedeniyle, kabuk program çıktısından önce bir bilgi istemi döndürdü. Üç örnek de wcnormal olarak sonlandırıldı.


1
In Bash yapabilirsiniz yazarak güvenli bir sürü yoluyla /tmp/data/{0,1,2}. Sonra tekrar, mkfifo
bash'ta proses ikameini

2
/ Dev / data0 ile / tmp / data0 arasında değişiklik yapmak isteyebilirsiniz. Ayrıca, soruyu kabaca agnostik bir şekilde yanıtladığınız için teşekkür ederiz. Bu, herkesin bash kullandığını varsaymaktan daha faydalı.
abonet

15

Doğru anladıysam, sen eşdeğer aradığınız tee file1 file2 file3ziyade yazma üç dosyalara aynı verileri daha file1, file2ve file3, sen borusuna üç komutları içine aynı veriyi istiyor cmd1, cmd2ve cmd3yani

… | ??? cmd1 cmd2 cmd3

eşdeğer olmalıdır

… | cmd1 &
… | cmd2 &
… | cmd3 &

bunun dışında sadece bir kez çalıştırılabilir.

Bunu yapmanın iki yolu var.

Ksh93, bash ve zsh, proses ikamesini destekler . Bu, bir komutun argümanına, yazıldığında, bir komuta girdi olarak veri ileten bir dosya olmasını sağlayan boruların genelleştirilmesidir (ayrıca, komuttan okunan veri çıktısını alan bir veri varyantı da vardır) . Yani,

echo hello | tee >(cmd1)

baskılar hellostandart çıktıya ve ek olarak çalışır cmd1ile hellogirdi olarak kullanılmaktadır.

Örneğin, girişini çoğaltmak somecommandve ikisine de geçirmek istiyorsanız, cmd1vecmd2

somecommand | tee >(cmd1) | cmd2

Eğer kabuğunuz işlem değişimini desteklemiyorsa, bunun yerine adlandırılmış yöneltmeler kullanabilirsiniz. Bunun nasıl çalıştığı için Arcege'in cevabına bakınız . Adlandırılmış borular, işlem değiştirme yerine daha uygundur, çünkü onları oluşturmanız, silmeniz ve işlemleri el ile başlatıp senkronize etmeniz gerekir. Tamamen taşınabilir olma avantajına sahipler, ancak tüm mermiler işlem değiştirmeyi desteklemiyor. Ayrıca işlem ikame edilmediklerinin dışındaki senaryolarda da kullanılabilirler.

Kaputun altında, bazı sistemlerde, işlem ikame işlemi dahili olarak adlandırılmış yöneltmeler kullanır. Yine de çoğu sistemde, dosya tanımlayıcılarını temsil eden adlandırılmış dosyalara dayanır .


5
Ayrıca bkz peegelen moreutils.
Stéphane Chazelas

İşlem sübstitüsyonunun ksh88 tarafından eklendiğine dikkat edin.
Stéphane Chazelas

6

En azından içerisinde mkfifoişlem değiştirmeyi kullanarak atlayabilirsiniz :

command -option1 -option2 argument | tee >(cmd1) >(cmd2) >(cmd3)

veya Arcege'nin örneğini benimsemek

tee >(wc -l) >(wc -w) >(wc -c) < /etc/passwd >/dev/null

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.