поток битов «cat» без EOF

#bash

#bash

Вопрос:

У меня есть файл, открытый как для чтения, так и для записи, и я связал этот файл с файловым дескриптором 3 , exec 3<>/dev/udp/10.10.10.1/161 т.Е. Когда я перенаправляю созданный UDP-пакет в файловый дескриптор 3 и получаю ответ, то как я могу прочитать его из файлового дескриптора 3 ? Обычные инструменты, такие как cat или read не работают хорошо, так как UDP-пакет (по сути, просто битовый поток), полученный в качестве ответа, не имеет новой строки или EOF и, например cat , не знает, что данных больше не ожидается. Например, здесь вы можете увидеть, как я относился к SIGINT cat:

 $ cat <amp;3 
0Gpublic�:�0,0 C1841.local^C
$ 
 

Я хотел бы проверить, были ли какие-либо данные UDP, полученные с 10.10.10.1, и это означает, что если файловый дескриптор 3 содержит некоторые данные (даже один бит), то ответ был получен.

Комментарии:

1. Вы пробовали head -c1 вместо cat ?

2. @Felix Frank head -c1 работает нормально, пока в файле есть данные. В случае отсутствия данных (например, если ответ UDP не был получен), head будет ожидать ввода. Это можно было бы решить, если head бы у него была аналогичная опция timeout( -t ), подобная read has ..

Ответ №1:

Ваша проблема в том, что вы не можете правильно распознать конец пакета. Как вы заметили, нет указателя EOF (например, специального символа или события закрытия файла или подобного). Вместо этого все, что вы можете сделать, это либо

  • считывайте символы фиксированного размера (в случае, если ваши пакеты имеют фиксированный размер) или
  • считывайте отдельные токены (возможно, байты) до тех пор, пока синтаксис вашего пакета не укажет, что он завершен или
  • считывайте, пока не наступит тайм-аут.

Первые два находятся под вашей ответственностью, если это возможно.

Последнее может быть достигнуто с помощью a cat в подоболочке, которую вы уничтожаете через определенное время:

 cat <amp;3 amp; pid=$!
sleep 0.1
kill "$pid" 2>/dev/null
 

Поместите это в функцию, и каждый вызов будет длиться 0,1 с и выводить то, что можно прочитать за это время.

Комментарии:

1. спасибо за объяснение! Я, наконец, пошел read -n 1 -t 2 <amp;3 . В случае, если в файле есть хотя бы какие-то данные read , он завершится с 0, а в случае, если файл пуст, read тайм-аут через две секунды и будет иметь ненулевой код выхода.