Bir işlemden diğerine aktarılan bayt sayısını sayma


17

Verileri bir işlemden diğerine ileten bir kabuk komut dosyası çalıştırıyorum

process_a | process_b

İki program arasında kaç bayt geçirildiğini öğrenmenin bir yolu var mı? Şu anda düşünebildiğim tek çözüm, stdin'den okuyan, stdout'a yazan ve aktarılan tüm verileri sayan, sayımı bir ortam değişkeninde saklayan küçük bir c programı yazmak olacaktır:

process_a | count_bytes | process_b

Daha temiz bir çözümü olan var mı?

Yanıtlar:


16

DD ile boru. dd'nin varsayılan girişi stdin ve varsayılan çıkışı stdout'tur; stdin / stdout G / Ç işlemini bitirdiğinde, stderr'a ne kadar veri aktarıldığını bildirir.

Eğer dd çıktısını yakalamak istiyorsanız ve diğer programlar zaten stderr ile konuşursa, başka bir dosya tanımlayıcı kullanın. Örneğin,

$ exec 4>~/fred
$ input-command | dd 2>&4 | output-command
$ exec 4>&-

2
execDosyayı doğrudan atlayıp doğrudan dosyaya gönderemez misiniz ? input-command | dd 2>~/fred | output-command
sonraki duyuruya kadar duraklatıldı.

2
Ah, evet. Görünüşe göre "o" anlardan birine sahiptim, üzgünüm.
Phil P

28

Boru görüntüleyicisini pv kullanın . Harika bir araç. Bir kez öğrendikten sonra onsuz nasıl yaşadığınızı asla bilemezsiniz.

Ayrıca bir ilerleme çubuğu ve aktarımın 'hızını' da gösterebilir.


Aramamda buna rastlamıştım, ancak başka bir işlemde kullanabilmem için aktarılan bayt sayısı ile bir değişken ayarlamam gerekiyor.
Simon Hodgson

Kullanım örneği: cat file | pv -bdosyanın boyutunu döndürür.
rodorgas

6

process_a | tee >(process_b) | wc --bytesçalışabilir. Daha sonra, wcsayısını istediğiniz yere yönlendirebilirsiniz . Bir process_bşey çıktılar stdout/ stderralırsanız, muhtemelen bunu bir yere yönlendirmeniz gerekecektir /dev/null.

Hafifçe örneklenmiş bir örnek için:

filestore:~# cat document.odt | tee >(dd of=/dev/null 2>/dev/null) | wc --bytes
4295

Açıklama yoluyla: teeçıktıyı birden fazla dosyaya (artı stdout) yönlendirmenize izin verir ve >()yapı bash'ın "işlem ikamesi" dir, bu da bir işlemi bu durumda salt yazılır bir dosyaya benzetir, böylece dosyalara olduğu kadar süreçlere de yönlendirebilirsiniz ( birçok işleme çıktı göndermek için kullanma örneği için buraya bakın veya bu soru + cevaptee ).


Bu çözümü seviyorum, ne yazık ki (BusyBox) kullandığım shelll> () gösterimini desteklemiyor gibi görünüyor, ama sonra ne yaptığımı yapmanın bir yolunu sağlıyor.
Simon Hodgson

Evet, bu özelliğe sahip olmak için oldukça eksiksiz bir bash'a ihtiyacınız var - bu yaygın olarak kullanılmayan bir şeydir, bu yüzden kısaltılmış kabuklardan sıyrılır (daha fazla veya daha az bash uyumlu olma hedefi olanlar bile) yerden kazanmak için busybox gibi.
David Spillett

1

Partiye geç kaldığımı biliyorum, ama bu yararlı konuyu geliştirebilecek iyi bir cevabım olduğuna inanıyorum.
Bu @Phil P ve @David Spillett cevaplarının bir karışımıdır, ancak:

  • @Phil P'den farklı olarak, yeni bir dosya oluşturmaktan kaçınır
  • @David Spillett'inkinden farklı olarak, boru hattı yapısını korur

Bayt sayısı, işlem_ çıktıları ile birlikte stdout'a yazdırılır.
Çıktı ile çalışırken bayt içeren satırı tanımlamak için bir önek kullanabilirsiniz ( Bytes:örnekte).

exec 3>&1
process_a | tee >({ echo -n 'Bytes:'; wc -c; } >&3) | process_b
exec 3>&-

UYARI:
Çıktıdaki satırların sırasına güvenmeyin
Sipariş öngörülemez ve aynı komut dosyasını aynı parametrelerle çağırırken bile her zaman farklı olabilir!


Ne yazık ki, hala sadece bash bir yapı ...
Mikhail T.
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.