Підрахуйте кількість байтів, що передаються від одного процесу до іншого


17

Я запускаю скрипт оболонки, який передає дані з одного процесу в інший

process_a | process_b

Хтось знає спосіб дізнатися, скільки байтів було передано між двома програмами? Єдиним рішенням, на який я зараз можу придумати, було б написати невелику програму c, яка читає з stdin, записує в stdout і рахує всі передані дані, зберігаючи підрахунок у змінній середовища, наприклад:

process_a | count_bytes | process_b

У когось є більш акуратне рішення?

Відповіді:


16

Труба через дд. Типовим входом dd є stdin, а вихідним типом - stdout; коли він закінчить stdin / stdout I / O, він повідомить stderr про кількість переданих даних.

Якщо ви хочете зафіксувати вихід dd та інші програми, які вже розмовляють зі stderr, тоді використовуйте інший файловий дескриптор. Наприклад,

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

2
Не могли ви пропустити execта просто вивести файл у файл безпосередньо? input-command | dd 2>~/fred | output-command
Призупинено до подальшого повідомлення.

2
Так, так. Я, мабуть, мав один із "тих" моментів, вибачте.
Філ П

28

Використовуйте pv -переглядач труб. Це чудовий інструмент. Коли ви дізнаєтесь про це, ви ніколи не дізнаєтесь, як жили без цього.

Він також може показати вам смугу прогресу та "швидкість" передачі.


Під час пошуку я натрапив на це, але мені це потрібно для встановлення змінної з кількістю переведених байтів, щоб я міг використовувати її в іншому процесі.
Саймон Ходжсон

Приклад використання: cat file | pv -bповерне розмір файлу.
rodorgas

6

process_a | tee >(process_b) | wc --bytesможе спрацювати. Потім ви можете переспрямувати wcлічильник на те, куди вам це потрібно. Якщо process_bвиводить що-небудь до stdout/, stderrвам, ймовірно, потрібно буде перенаправити це кудись, якщо тільки /dev/null.

Для трохи надуманого прикладу:

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

Як пояснення: teeдозволяє направляти вихід на декілька файлів (плюс stdout), а >()конструкція - це «заміна процесу» bash, що робить процес схожим на файл, що пише лише для запису, в цьому випадку ви можете перенаправлятись на процеси, а також на файли ( дивіться тут , або це питання + відповідь для прикладу використання teeдля надсилання результатів у багато процесів).


Мені подобається це рішення, на жаль, оболонка, яку я використовую (BusyBox), схоже, не підтримує позначення> (), але він забезпечує спосіб робити те, що я хочу.
Саймон Ходжсон

Так, вам потрібен досить повний баш, щоб мати цю функцію - це та річ, яка зазвичай не використовується, тому позбавляється від обрізаних снарядів (навіть тих, хто має на меті бути більш-менш сумісними баш) як-от зайнятий, щоб заощадити місце.
Девід Спіллетт

1

Я знаю, що я спізнююсь на вечірку, але я вважаю, що маю гарну відповідь, яка може посилити цю корисну нитку.
Це поєднання відповідей @Phil P і @David Spillett, але:

  • інакше від @Phil P 's, це дозволяє уникнути створення нового файлу
  • відрізняється від @David Spillett's, він підтримує структуру трубопроводу

Підрахунок байтів друкується до stdout разом з будь-яким результатом process_b.
Ви можете використовувати префікс для ідентифікації рядка, що містить байти під час роботи з висновком ( Bytes:у прикладі).

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

ПОПЕРЕДЖЕННЯ:
Не покладайтеся на порядок рядків у висновку
Порядок непередбачуваний і він завжди може відрізнятися, навіть коли викликає той самий сценарій з тими ж параметрами!


На жаль, це все-таки лише конструктивна конструкція ...
Михайло Т.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.