#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
тайм-аут через две секунды и будет иметь ненулевой код выхода.