The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]



"Как ускорить выполнения скрипта shell (проверка POS принтера)"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (Shell скрипты)
Изначальное сообщение [ Отслеживать ]

"Как ускорить выполнения скрипта shell (проверка POS принтера)"  +/
Сообщение от Pablicemail (?), 17-Авг-20, 16:23 
В общем, есть компьютеры к ним подключены чековые принтеры Posiflex, необходимо при загрузке системы проверить подключен ли чековый принтер к COM порту или нет, если подключен то сделать симлинк для freerdp.
Накидал shell скрипт который проверяет на двух скоростях подключен ли принтер или нет, но проблема вывалилась следующая: если к порту ничего не подключено то проверка выполняется долго ~ 30-35сек. Не могу никак победить проблему, подскажите может кто сталкивался, реализовывал примерно такое.

Udev при нахождении платы расширения в компе сохраняет переменные окружения примерно так:
RS232_4_DEVICE=/dev/ttyS4
RS232_5_DEVICE=/dev/ttyS5


Далее скрипт:
#! /bin/sh

. $TS_GLOBAL

case "$1" in
    init)
        info_msg "Starting POS printer search... "
        for dev in 0 1 2 3 4 5 6 7 8 9; do
            if [ -n "`eval echo '$RS232_'$dev'_DEVICE'`" ] ; then
                device=`eval echo '$RS232_'$dev'_DEVICE'`
                # Проверяем порты на скоростях
                for speed in 19200 115200
                do
                    prn_found=0
                    #Устанавливаем на порту скорость и некоторые параметры
                    /bin/stty -F $device $speed raw -echo clocal crtscts cread &
                    #Когда на порту ничего нет, ждем и убиваем процесс stty
                    waitpid=$!
                    while kill -0 ${waitpid} 2>/dev/null ; do
                        sleep 1
                        /bin/kill -0 ${waitpid} 2>/dev/null
                        if [ $? -eq 0 ]; then
                            #Убиваем процесс, заканчиваем работу скрипта, похоже там ничего на пор ту не висит
                            kill ${waitpid} 2>/dev/null
                            break
                        else
                            #Процесса уже нет, есть вероятность что к порту подключено оборудование
                            #Редиректим вывод с порта в FD
                            exec 3<$device
                            #Редиректим вывод с FD в файл
                            /bin/cat <&3 > /tmp/ttyDump.dat &
                            #сохраняем PID для cat
                            PID=$!
                            #Посылаем команду в порт
                            printf "\x1d\x49\x43" > $device
                            #Ждем вывод
                            sleep 1
                            #Убиваем редирект cat
                            kill $PID
                            #Подавляем вывод "Terminated"
                            wait $PID 2>/dev/null
                            #освобождаем FD
                            exec 3<&-
                            AURA=`cat /tmp/ttyDump.dat | sed 's/_//g' | sed 's/^@//g'`
                            if [ -n "$AURA" ]; then
                                #Принтер отозвался на порту таком то и скорости такой то...
                                prn_found=1
                                logger -t $0 "POS printer model: AURA $AURA found on port $device speed $speed"
                                rm -rf /tmp/ttyDump.dat
                                # создаем символическую ссылку POSPRN для freerdp
                                for num in 0 1 2 3 4 5 6 7 8 9; do
                                    if [ -L /dev/POSPRN$num ] ; then
                                        if [ `readlink /dev/POSPRN$num` == $device ] ; then
                                            break;
                                        fi
                                    elif [ ! -L /dev/POSPRN$num ]; then
                                            ln -s $device /dev/POSPRN$num
                                            break;
                                    fi
                                done
                            else

                                logger -t $0 "POS printer model: AURA not found on port $device speed $speed"
                                rm -rf /tmp/ttyDump.dat
                            fi
                            break
                        fi
                    done
                    if [ "$prn_found" -eq "1" ]; then
                        #Если нашел принтер, прекращаю проверку по скоростям
                        success_msg "POS printer model: AURA $AURA found on port $device speed $speed"
                        break
                    fi
                done
            fi
        done
    ;;
    help)
        echo "Usage: $0 init"
    ;;
    *)
        exit 1
    ;;
esac

exit 0

Возможно можно оптимизировать некоторые блоки скрипта, критику приемлю

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения [Сортировка по ответам | RSS]

1. Сообщение от Аноним (1), 18-Авг-20, 08:45   +/
> Udev при нахождении платы расширения в компе сохраняет переменные окружения примерно так:
> for dev in 0 1 2 3 4 5 6 7 8 9; do

вероятно я чего-то не понял, но почему не дергать скрипт через udev при обнаружении устройства?

Ответить | Правка | Наверх | Cообщить модератору
Ответы: #2, #3

2. Сообщение от ss (??), 18-Авг-20, 11:00   +/
>> Udev при нахождении платы расширения в компе сохраняет переменные окружения примерно так:
>> for dev in 0 1 2 3 4 5 6 7 8 9; do
> вероятно я чего-то не понял, но почему не дергать скрипт через udev
> при обнаружении устройства?

А устройство на сомпорту както само автообнаружается?

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #1 Ответы: #4, #5

3. Сообщение от Pablicemail (?), 18-Авг-20, 11:14   +/
>> Udev при нахождении платы расширения в компе сохраняет переменные окружения примерно так:
>> for dev in 0 1 2 3 4 5 6 7 8 9; do
> вероятно я чего-то не понял, но почему не дергать скрипт через udev
> при обнаружении устройства?

udev линеен, нельзя запускать что то долгое, устройство rs232 само по себе не обнаруживается, к нему надо подключится и послать команду.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #1 Ответы: #6

4. Сообщение от Pablicemail (?), 18-Авг-20, 11:15   +/
>>> Udev при нахождении платы расширения в компе сохраняет переменные окружения примерно так:
>>> for dev in 0 1 2 3 4 5 6 7 8 9; do
>> вероятно я чего-то не понял, но почему не дергать скрипт через udev
>> при обнаружении устройства?
> А устройство на сомпорту както само автообнаружается?

нет, обычный COM порт

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #2

5. Сообщение от Аноним (1), 18-Авг-20, 17:10   +/
вообще без понятия. Неправильно понял про плату расширения
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #2

6. Сообщение от Аноним (1), 18-Авг-20, 17:18   +/
> udev линеен, нельзя запускать что то долгое

даже форки не пройдут?

еще одно "гениальное" предложение, подсмотренное у одного из производителей принтеров: запустить 10 процессов. Тот, который попал на принтер, сделает симлинки, остальные отомрут по таймауту

или есть что-то еще, что ожидает отрабатывания скрипта?

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #3 Ответы: #8

7. Сообщение от ACCA (ok), 18-Авг-20, 22:04   +/
Воткни принтер через переходник COM-USB и не возись с COM портами напрямую.
Ответить | Правка | Наверх | Cообщить модератору
Ответы: #9, #10

8. Сообщение от Pablicemail (?), 19-Авг-20, 05:39   +/
>> udev линеен, нельзя запускать что то долгое
> даже форки не пройдут?
> еще одно "гениальное" предложение, подсмотренное у одного из производителей принтеров:
> запустить 10 процессов. Тот, который попал на принтер, сделает симлинки, остальные
> отомрут по таймауту
> или есть что-то еще, что ожидает отрабатывания скрипта?

Как вариант...
Вообще это бездисковая станция, при загрузке проверяет что подключено к станции и подготавливает почву для freerdp

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #6

9. Сообщение от Pablicemail (?), 19-Авг-20, 05:40   +/
> Воткни принтер через переходник COM-USB и не возись с COM портами напрямую.

не вариант

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #7

10. Сообщение от ss (??), 19-Авг-20, 08:30   +/
> Воткни принтер через переходник COM-USB и не возись с COM портами напрямую.

Мне кажется нет никакой разницы через переходник оно или нет если надо ждать ответа от устройства "на том конце" и единственный путь определить что его там нет - отвал по таймауту.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #7 Ответы: #11

11. Сообщение от Pablicemail (?), 19-Авг-20, 09:21   +/
>> Воткни принтер через переходник COM-USB и не возись с COM портами напрямую.
> Мне кажется нет никакой разницы через переходник оно или нет если надо
> ждать ответа от устройства "на том конце" и единственный путь определить
> что его там нет - отвал по таймауту.

Не могу понять откуда 30секунд таймаута, делал так stty -F /dev/ttyS4 -icanon min 0 time 3, все равно 30 сек

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #10 Ответы: #12

12. Сообщение от ss (??), 19-Авг-20, 09:34   +/
>>> Воткни принтер через переходник COM-USB и не возись с COM портами напрямую.
>> Мне кажется нет никакой разницы через переходник оно или нет если надо
>> ждать ответа от устройства "на том конце" и единственный путь определить
>> что его там нет - отвал по таймауту.
> Не могу понять откуда 30секунд таймаута, делал так stty -F /dev/ttyS4 -icanon
> min 0 time 3, все равно 30 сек

Это полное время работы скрипта? Потому что момент когда вы определяете занят порт или нет- имеет задержку 1 секунда.
То есть весь последующий код - выполняется (или не должен выполнятся) через 1 секунду после того как вы обнаружили что "порт пуст". Можно предположить что ваша проверка пуст ли порт- некорректна, и последующий 30 секундный таймаут- результат того что на пустом порту отрабатывает вот тот весь остальной код.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #11 Ответы: #13

13. Сообщение от Pablicemail (?), 19-Авг-20, 10:17   +/
>>>> Воткни принтер через переходник COM-USB и не возись с COM портами напрямую.
>>> Мне кажется нет никакой разницы через переходник оно или нет если надо
>>> ждать ответа от устройства "на том конце" и единственный путь определить
>>> что его там нет - отвал по таймауту.
>> Не могу понять откуда 30секунд таймаута, делал так stty -F /dev/ttyS4 -icanon
>> min 0 time 3, все равно 30 сек
> Это полное время работы скрипта?

нет, это время проверки порта на одной скорости

> Можно предположить что ваша проверка пуст ли порт- некорректна, и последующий 30
> секундный таймаут- результат того что на пустом порту отрабатывает вот тот
> весь остальной код.

скрипт немного переделал:
1. не имеет смысла искать принтер на другой скорости если мы уже нашли на предыдущей (если на порту есть принтер скрипт отрабатывается за 2 сек не важно на какой скорости висит принтер)
2. попытался поиграть с stty если долго висит, наверняка на порту ничего нет, убиваю stty и дальше не проверяю порт

на тестовом компьютере проверяю работает время определения 2сек, пустой порт не проверяет все вроде пучком. при загрузке скрипт пытается 1 раз проверить пустой порт... не пойму что не так...

из лога при загрузке:
Aug 19 13:09:50 PnX-D945 user.notice /etc/rc2.d/S81aura: Starting POS printer search...
Aug 19 13:09:52 PnX-D945 user.notice /etc/rc2.d/S81aura: POS printer model: AURA PP-7000-II found on port /dev/ttyS4 speed 19200
Aug 19 13:10:24 PnX-D945 user.notice /etc/rc2.d/S81aura: POS printer model: AURA not found on port /dev/ttyS5 speed 19200

из лога на загруженом:
Aug 19 14:14:50 PnX-D945 user.notice ./aura: Starting POS printer search...
Aug 19 14:14:52 PnX-D945 user.notice ./aura: POS printer model: AURA PP-7000-II found on port /dev/ttyS4 speed 19200

что изменилось не пойму

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #12


Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Спонсоры:
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2020 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру