LINUX.ORG.RU

Оптимизация bash-скрипта.

 , , ,


1

3

Коллеги, поделитесь пожалуйста советами, как реализовать мою задачу на BASH-е с максимальной эффективностью и быстродействием ? Суть скрипта состоит в чтении _бинарного_ файла и передаче его содержимого в COM-порт, добавляя в процессе передачи управляющие двоичные коды. Данную задачу реализовал как смог:

#!/bin/bash
COUNTER=0 
FILE=$1
FILESIZE=$(stat -c%s "$FILE");
echo -en "\xFE\xFE\xFE\xFE" > /dev/ttyUSB0      # Синхронизируем поток данных. После исполнения устройство готово принять старший байт адреса
while [ "$COUNTER" -lt $FILESIZE ]
do
    let HR=COUNTER/256
    let LR=COUNTER%256
    hLR=`printf "%02X" $LR`
    hHR=`printf "%02X" $HR`
    hBT=`dd if=$FILE bs=1 count=1 skip=$COUNTER 2>/dev/null | hexdump -v -e '/1 "%02X"'`
    echo -en "\xFF\x$hHR\x$hLR\xFF\x$hBT" > /dev/ttyUSB0        # Паттерн чтения/записи байта в адрес $hHR$hLR

    let COUNTER=COUNTER+1
done
echo -en "\xFE" > /dev/ttyUSB0                  #  Перевести контроллер в состояние запрета записи данных

тапёра не бейте играет как умеет :))

P.S. Понимаю, что у меня производится много лишних и ненужных преобразований типа бинарные данные в текстовый HEX-формат, затем обратно в бинарные и т.д, что очень сильно тормозит обработку, но в силу редкого использования shell-а для меня затруднительно выбрать оптимальный путь.

Если скрипты должны быть портабельными и хоть как-то побыстрее, то обычно выбирают питон.

А ещё ты открываешь файл и принимаешь оттуда всего один байтик, а ведь открывать файл это затраты.

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

что очень сильно тормозит обработку

Ты калькулятором с дискет читаешь что ли?
Что именно и где именно тормозит?

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

Нет, задачи портабельности нет, да и перенесу я эту логику в дальнейшем на C, но сейчас надобно наваять для простоты отладки в виде скрипта. Согласен, что чтение по байту из файла это не айс, но иначе требуется буфер до 64К в который надо за раз считывать, а затем в перемешку с управляющими кодами слать в порт.

HandBreak
() автор топика

с максимальной эффективностью и быстродействием

Окстись, ты работаешь с COM портом, там эфективность и быстродействие близко не нужны. Если пишешь на баше, напиши хотя бы так чтобы оно хоть как-то читалось. А если хочешь эффективности и быстродействия, это возможно только на полноценном ЯП. C или питон, например. Тут и читабельность автоматически будет.

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

Тормозят процесс более всего эти три операции:

    hLR=`printf "%02X" $LR`
    hHR=`printf "%02X" $HR`
    hBT=`dd if=$FILE bs=1 count=1 skip=$COUNTER 2>/dev/null | hexdump -v -e '/1 "%02X"'`
Среди них очевидно более всего побайтовое чтение файла, а следом за ним соответствующее преобразование hexdump-ом

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

Ну в моём случае COM-виртуальный и аппаратно прокачивает до 1мБайт/с, тогда как сейчас скорость выходит порядка 1 кБайт/с. Впрочем здесь в большей мере вопрос моего «перфекционизма» нежели необходимости. Просто глядя на то что написал понимаю что это очень не эффективное решение и хотелось бы понять как можно решать подобные задачи более красиво.

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

Ну вот ты сделаешь на сях и будешь читать потоком - будет хорошо, а так ты с помощью dd считываешь байтик не из начала даже, закрываешь и пайпаешь в hexdump. И всё по новой каждый раз.

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

1мБайт/с

1 миллибайт? Даже если имелся в виду МБайт, это жалкие копейки.

как можно решать подобные задачи более красиво

Более красиво - точно не на bash.

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

Так вот меня как раз и интересует, можно ли в баше как-нибудь более рационально читать бинарник, обрабатывать и передавать дальше

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

Быстрей на сях написать, чем закрывать бутылочные горлышки в баше.

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

Весь файл сразу через hexdump записать в массив bash'а. Там, конечно, надо смотреть, чтобы у системы ОЗУ хватило, потому, что баш берёт памяти под массив заметно больше, чем данных в массиве. Но, если в файле десятки килобайт, то вполне сработает.

Не верю, что pritnf более всего тормозит. Он ведь встроенный в bash. Тормозит dd и hexdump, причем, основные тормоза в fork()+exec().

mky ★★★★★
()

barbos - входной файл

od -t d1 barbos | awk '
BEGIN { printf "\xFE\xFE\xFE\xFE"; counter = 0; }
NF > 1 { for (i=2;i<=NF;i++){
printf "\xff%c%c\xff%c",counter / 256, counter % 256, $i; 
counter++;
         }
       }
END { printf "\xfe" }
'
io ★★
()
Ответ на: комментарий от mky

Не верю, что pritnf более всего тормозит.

А ОП его зачем-то в подоболочке запускает.

Весь файл сразу через hexdump записать в массив bash'а.

Массив не нужен:

#!/bin/bash

file="$1"

echo -en "\xFE\xFE\xFE\xFE" > /dev/ttyUSB0

counter=0
while read hBT
do
    (( HR = counter / 256,
       LR = counter % 256 ))
    printf -v hLR "%02X" "$LR"
    printf -v hHR "%02X" "$HR"
    echo -en "\xFF\x$hHR\x$hLR\xFF\x$hBT" > /dev/ttyUSB0
    (( counter++ ))
done < \
     <(od --address-radix=n --format=x1 --width=1 --output-duplicates "$file")

echo -en "\xFE" > /dev/ttyUSB0

Не проверял, могут быть ошибки вплоть до синтаксических.

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

Мало того. Я еще в /dev/ttyUSB0 результат не отправил. Но нельзя не согласиться, что

od -vt d1 barbos | ...

будет лучше.

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

Так я вроде написал что более всего тормозят dd и hexdump. Всё верно. Сам тем временем попробовал пойти по пути чтения за раз всего файла в переменную через hexdump с последующим парсингом этой переменной (или массива).

HandBreak
() автор топика

+1, для более менее средних скриптов - Python то что надо, я как-то даже полюбил этот язык...

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от HandBreak

Тормозят не сами команды, а их запуск. И Zmicier правильно показал, что ″printf″ нужно с опцией ″-v″.

mky ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.