LINUX.ORG.RU
ФорумAdmin

Условие для потока файла /dev/ttyusb /dev/usbmon0

 , ,


1

1

Добрый день, подскажите пожалуйста как реализовать скрипт, который сравнивал бы строки из вывода файла и выполнял действие при совпадении.

Например, постоянно выводятся данные через hexdump такого вида:

0000 0001 0000 0001 0000 0000 0000 0000
6a00 c400 0484 f010 f721 0100 4f00 0012
0000 0000 5800 cfac 1f15 0b00 7d00 00f5
0600 00f7 0000 00e8 0022 0003 0000 1649

И нужно через условие или как-то выполнить действие при совпадении строки:

if [[ hexdump /dev/usbmon0 == "0000 0001 0000 0001 0000 0000 0000 0000"]]
then
commands;
commands;
commands;
fi

В продолжении этой темы - Как считать любые данные с usb порта?

PS Пишите, что поправить если не понятно

Ответ на: комментарий от bugfixer

если там действительно бинарник (а не выхлоп hexdump’а) забудьте всё что я раньше сказал про getline()

Та я и сам провтыкал(. Вспомнил о бинарных данных только в контексте strstr().

Возвращаемся к истокам)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void) {
    const char *str = "c8bc19b2de05b621";
    const int bytes_count = strlen(str) / 2;
    const size_t read_max = 128;
    char file_buf[read_max];

    unsigned char buffer[bytes_count];
    for (int i = 0; i < bytes_count; ++i) {
        sscanf(str + 2 * i, "%2hhx", &buffer[i]);
    }

    FILE *f = fopen("infile.txt", "rb");
    if (!f) {
        perror("Cannot open file:");
        return EXIT_FAILURE;
    }

    size_t n_read = fread(file_buf, 1, read_max, f);

    char *ptr = memchr(file_buf, buffer[0], n_read);
    if (n_read >= bytes_count && ptr) {
        if (memcmp(ptr, buffer, bytes_count) == 0) {
            printf("Found str on position %lu\n", (size_t)(ptr - file_buf));
            return EXIT_SUCCESS;
        }
    }

    puts("Couldn't find str in file");
    return EXIT_FAILURE;
}
iron ★★★★★
()
Ответ на: комментарий от iron

Ты лучший, пожал бы руку за твой энтузиазм

▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▓▓▓▓▒▓▓▒▒▓▓▒▒▓▓▓▓▒▒▒▓▓▓▓▒▒▓▓▓▓▒▒
▒▓▓▒▒▒▒▓▓▒▒▓▓▒▓▓▒▒▓▓▒▓▓▒▒▒▒▓▓▒▒▓▓▒
▒▒▓▓▓▒▒▓▓▒▒▓▓▒▓▓▓▓▓▒▒▓▓▓▓▒▒▓▓▓▓▓▓▒
▒▒▒▒▓▓▒▓▓▒▒▓▓▒▓▓▒▒▒▒▒▓▓▒▒▒▒▓▓▒▓▓▒▒
▒▓▓▓▓▒▒▒▓▓▓▓▒▒▓▓▒▒▒▒▒▒▓▓▓▓▒▓▓▒▒▓▓▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

SaintAnd
() автор топика
Ответ на: комментарий от iron

Возвращаемся к истокам)

  1. нужен цикл вокруг memchr() + memcmp(), подумайте о файле с содержимым «01 01 02 03 04 …» и попытке в этом найти «01 02 03 04».
  2. если memchr() остановился слишком близко к концу буфера - memcmp() делать нельзя.
  3. я не знаю задумывался ли поиск только в первых 128 байтах, но скорее всего хотелось искать во всем файле - и тогда нужен цикл вокруг fread(), причём нужно очень аккуратно смотреть на «хвосты»: как только memchr() остановился ближе к концу буфера чем длинна needle - проще всего двинуть (memmove()) «хвост» в начало буфера и читать из файла дальше. Это можно продолжать оптимизировать, но на коротких needle «овчинка выделки не стоит», имхо.
  4. Не знаю откуда циферка в 128 байт взялась - для обычных файлов «маловато будет», что-то мне подсказывает Вы на самом деле non-blocking read хотите с select(). Но думаю что на этом этапе с non-blocking / async IO Вам разобраться будет сложновато, даже с самой концепцией.

ПыСы. Мне бы очень не хотелось чтобы хоть что-то из того что я сказал воспринималось как какая-то извращённая форма издевательства - я честно помочь пытаюсь указывая на очевидные ляпы.

bugfixer ★★★★★
()
Последнее исправление: bugfixer (всего исправлений: 2)
Ответ на: комментарий от bugfixer

Все это логично и правильно. НО, автор топика сначала пишет о сравнении строк из вывода файла. Но при этом в предыдущей теме речь идет о считывании данных с USB устройства. В итоге не понятно откуда беруться данные. По сему, зачем сейчас «доить сферического коня в вакууме» с чтением файла, если в итоге читать нужно не с него. В выше представленных примерах есть концепт того, как можно выполнять поиск последовательности бинарных данных. Все остальное – уже детали.

Если топикстартер более подробнее расскажет откуда ему нужно доставать данные, то можно было бы по фану что-то придумать. А еще лучше, иметь возможность воспроизвести у себя подобный поток данных.

Но думаю что на этом этапе с non-blocking / async IO Вам разобраться будет сложновато

Если бы я писал для себя, я бы на входящий поток данных подцепил бы kqueue() фильтр и парсил бы данные по мере их поступления.

iron ★★★★★
()
Ответ на: комментарий от iron

Все это логично и правильно.

Те ляпы на которые я указал - это логические ошибки которые приводят к неправильному поведению. Я даже не придираюсь к стилистике - оно тупо не работает (пока ещё).

Если бы я писал для себя, я бы на входящий поток данных подцепил бы kqueue()

Я не до конца понимаю к чему Вы ведёте - то что Вы до сих пор продемонстрировали от уровня «нам нужен kqueue» сильно далеко. Я уж молчу что оно BSD-specific (если мы об одном и том же).

ПыСы. И ссылка - битая, кстати.

bugfixer ★★★★★
()
Последнее исправление: bugfixer (всего исправлений: 1)
Ответ на: комментарий от bugfixer

Я не до конца понимаю к чему Вы ведёте

Я веду к тому, что не зная источник данных – невозможно подобрать оптимальный метод чтения с него. А вариантов может быть много: от тупого read() до aio_read(), epoll()/kqueue().

то что Вы до сих пор продемонстрировали от уровня «нам нужен kqueue» сильно далеко

kqueue() не является чем-то сложным и недостижимым. И тем более не является показателем уровня программерского мастерства.

iron ★★★★★
()
Ответ на: комментарий от iron

kqueue() не является чем-то сложным и недостижимым.

Знаете как говорят - «не боги обжигают горшки». Конечно ничего сверх-естественного там нет. Но Вы хотя-бы безглючный (пусть и медленный) «бинарный» strstr() напишите для начала. А потом мы вернёмся к kqueue.

bugfixer ★★★★★
()
Последнее исправление: bugfixer (всего исправлений: 1)