Чтение данных из канала и запись в стандартный вывод с задержкой между ними. Обрабатывать двоичные файлы тоже - PullRequest
3 голосов
/ 23 сентября 2009

Я около часа пытаюсь найти элегантное решение этой проблемы. Моя цель в основном написать команду канала управления пропускной способностью, которую я мог бы повторно использовать в различных ситуациях (не только для сетевых передач, я знаю о scp -l 1234). Что я хотел бы сделать, это:

  1. Задержка на X секунды.
  2. Считать Y количество (или меньше, чем Y, если не достаточно) данных из канала.
  3. Запись прочитанных данных в стандартный вывод.

Где:

  • X может быть 1..n.
  • Y может быть от 1 байта до некоторого высокого значения.

Моя проблема:

  • Он должен поддерживать двоичные данные, которые Bash не может хорошо обработать.

Дороги, которые я выбрал или хотя бы подумали:

  • Используя конструкцию while read data, он фильтрует все белые символы в кодировке, которую вы используете.
  • Использование dd bs=1 count=1 и цикл. dd, похоже, не имеет разных кодов выхода, когда что-то было в if и нет. Что затрудняет узнать, когда прекратить зацикливание. Этот метод должен работать, если я перенаправляю стандартную ошибку во временный файл, читаю его, чтобы проверить, было ли что-то передано (как в статистике, напечатанной на stderr), и повторите. Но я подозреваю, что это очень медленно, если используется на больших объемах данных, и если это возможно, я бы хотел пропустить создание каких-либо временных файлов.

Любые идеи или предложения о том, как решить эту проблему как можно более чисто с помощью Bash?

Ответы [ 4 ]

5 голосов
/ 16 февраля 2011

может быть pv -qL RATE ?

   -L RATE, --rate-limit RATE
          Limit the transfer to a maximum of RATE  bytes  per  second.   A
          suffix of "k", "m", "g", or "t" can be added to denote kilobytes
          (*1024), megabytes, and so on.
1 голос
/ 23 сентября 2009

Это не очень элегантно, но вы можете использовать какой-то трюк с перенаправлением, чтобы поймать количество байтов, скопированных dd, а затем использовать его как условие выхода для цикла while:

while [ -z "$byte_copied" ] || [ "$byte_copied" -ne 0 ]; do 
    sleep $X; 
    byte_copied=$(dd bs=$Y count=1 2>&1 >&4 | awk '$2 == "byte"{print $1}'); 
done 4>&1

Однако, если вы намерены ограничить пропускную способность передачи, я предлагаю вам использовать pv.

0 голосов
/ 23 сентября 2009

Как насчет использования head -c?

cat /dev/zero | head -c 10 > test.out

Дает вам хороший 10-байтовый файл.

0 голосов
/ 23 сентября 2009

Вы должны сделать это в bash? Вы можете просто использовать существующую программу, такую ​​как cstream ?

cstream соответствует вашей цели - команда канала с пропускной способностью, но не обязательно соответствует другим вашим критериям в отношении вашего конкретного алгоритма или языка реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...