Intereting Posts
«Запрос на распределение PTY не удалось на канале 0 stdin: не является tty», когда SSH'ing на сервер Debian привязать к строке с экранированными двойными кавычками Как заставить сообщения tmux оставаться дольше? Отсутствие выделения zsh-синтаксиса в tmux Создайте тестовый файл с большим количеством нулевых байтов Изменение имени пользователя по-прежнему оставляет старые следы Как добавить метки в iptables (цели MARK и CONNMARK) Как удалить соответствующие файлы из каталога A в каталоге B в командной строке? «python-software-properties» не имеет кандидата на установку при установке факела Debian 8 – Обновление Iptables при загрузке Ошибка ввода-вывода, но плохой блок не указан в syslog Java-код для копирования файлов с одной Linux-машины на другую Linux-машину Перекомпилируйте gcc со встроенной версией Перенаправление вывода с удаленного сервера найти файл с помощью определенного поиска в цикле while

Транспортировка данных в FIFO с помощью EOFs каждую секунду

Я пытаюсь передать некоторые необработанные двоичные данные до fifo (out.pipe) и гарантировать, что EOF отправляются через равные промежутки времени. Я не понимаю, почему следующая строка не будет делать то, что я хочу:

while true; do read -t 1 -N 128 line; echo -n $line > out.pipe; done 

Похоже, что когда истекает таймаут, $line получает пустое значение, и даже когда это не происходит, все строки новой строки удаляются из ввода. Это не мое понимание того, что должно произойти в соответствии с этим документом :

-N nchars

чтение возвращается после чтения точно символов nchars, а не ожидания полной строки ввода, если только EOF не встречается или не читается. Символы-разделители, встречающиеся на входе, не обрабатываются специально и не заставляют чтение возвращаться до тех пор, пока не будут прочитаны символы nchars.

-t таймаут

Причина чтения в тайм-аут и возврат отказа, если полная строка ввода (или заданное количество символов) не читается в течение таймаута секунд. таймаут может быть десятичным числом с дробной частью после десятичной точки. Эта опция эффективна только в том случае, если чтение считывает данные с терминала, канала или другого специального файла; он не влияет на чтение из обычных файлов. Если время чтения заканчивается, чтение сохраняет какой-либо частичный ввод, указанный в указанном имени переменной. Если timeout равно 0, чтение немедленно возвращается, не пытаясь прочитать и данные. Статус выхода равен 0, если входной файл доступен в указанном дескрипторе файла, в противном случае – ноль. Состояние выхода превышает 128, если превышено время ожидания.

Без параметра -N 128 на read и параметра -n на echo , это очень близко к тому, что я хочу. Проблема в том, что новые строки обрабатываются специальными и отправляются даже тогда, когда нет данных:

 while true; do read -t 1 line; echo $line > out.pipe; done 

Я тестировал, что входит в мою трубу, со следующей строкой:

 while true; do cat out.pipe; done 

Я протестировал отправку ввода через stdin, а также отправку данных HTTP с помощью echo -e "GET / HTTP/1.1\r\nHost: hostname\r\n\r\n" | nc localhost 80 | myreadcommand echo -e "GET / HTTP/1.1\r\nHost: hostname\r\n\r\n" | nc localhost 80 | myreadcommand echo -e "GET / HTTP/1.1\r\nHost: hostname\r\n\r\n" | nc localhost 80 | myreadcommand , который был очень запутан из-за одиноких символов.

Что я не понимаю? Есть ли лучший способ сделать это, что мне не хватает?

read странице руководства read также:

Завершающая <newline> (если таковая имеется) должна быть удалена из ввода, и результаты должны быть разделены на поля, как в оболочке, для результатов разложения параметров

Он также документирует множество исключений, основанных на том, какие параметры вы передаете ему, как обрабатывать новые строки. Чтение всей страницы руководства необходимо, если такие исключения имеют значение для вас.

Если вы хотите игнорировать определенные символы, такие как \r , которые можно легко выполнить с помощью sed :

 echo "hi\r\nI am a script" | sed "s/\r//g" 

Чтобы сделать замену более очевидной, вы можете заменить ее на что-то еще:

 echo "hi\r\nI am a script" | sed "s/\r/,/g" 

Также важно отметить, что использование параметра -e для echo позволяет интерпретировать специальные комбинации символов обратной косой черты, которые фактически не соответствуют реальному символу линии, присутствующему на входе.