В общем, есть компьютеры к ним подключены чековые принтеры 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
elselogger -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
;;
esacexit 0
Возможно можно оптимизировать некоторые блоки скрипта, критику приемлю
> Udev при нахождении платы расширения в компе сохраняет переменные окружения примерно так:
> for dev in 0 1 2 3 4 5 6 7 8 9; doвероятно я чего-то не понял, но почему не дергать скрипт через udev при обнаружении устройства?
>> Udev при нахождении платы расширения в компе сохраняет переменные окружения примерно так:
>> for dev in 0 1 2 3 4 5 6 7 8 9; do
> вероятно я чего-то не понял, но почему не дергать скрипт через udev
> при обнаружении устройства?А устройство на сомпорту както само автообнаружается?
>>> Udev при нахождении платы расширения в компе сохраняет переменные окружения примерно так:
>>> for dev in 0 1 2 3 4 5 6 7 8 9; do
>> вероятно я чего-то не понял, но почему не дергать скрипт через udev
>> при обнаружении устройства?
> А устройство на сомпорту както само автообнаружается?нет, обычный COM порт
вообще без понятия. Неправильно понял про плату расширения
>> Udev при нахождении платы расширения в компе сохраняет переменные окружения примерно так:
>> for dev in 0 1 2 3 4 5 6 7 8 9; do
> вероятно я чего-то не понял, но почему не дергать скрипт через udev
> при обнаружении устройства?udev линеен, нельзя запускать что то долгое, устройство rs232 само по себе не обнаруживается, к нему надо подключится и послать команду.
> udev линеен, нельзя запускать что то долгоедаже форки не пройдут?
еще одно "гениальное" предложение, подсмотренное у одного из производителей принтеров: запустить 10 процессов. Тот, который попал на принтер, сделает симлинки, остальные отомрут по таймауту
или есть что-то еще, что ожидает отрабатывания скрипта?
>> udev линеен, нельзя запускать что то долгое
> даже форки не пройдут?
> еще одно "гениальное" предложение, подсмотренное у одного из производителей принтеров:
> запустить 10 процессов. Тот, который попал на принтер, сделает симлинки, остальные
> отомрут по таймауту
> или есть что-то еще, что ожидает отрабатывания скрипта?Как вариант...
Вообще это бездисковая станция, при загрузке проверяет что подключено к станции и подготавливает почву для freerdp
Воткни принтер через переходник COM-USB и не возись с COM портами напрямую.
> Воткни принтер через переходник COM-USB и не возись с COM портами напрямую.не вариант
> Воткни принтер через переходник COM-USB и не возись с COM портами напрямую.Мне кажется нет никакой разницы через переходник оно или нет если надо ждать ответа от устройства "на том конце" и единственный путь определить что его там нет - отвал по таймауту.
>> Воткни принтер через переходник COM-USB и не возись с COM портами напрямую.
> Мне кажется нет никакой разницы через переходник оно или нет если надо
> ждать ответа от устройства "на том конце" и единственный путь определить
> что его там нет - отвал по таймауту.Не могу понять откуда 30секунд таймаута, делал так stty -F /dev/ttyS4 -icanon min 0 time 3, все равно 30 сек
>>> Воткни принтер через переходник COM-USB и не возись с COM портами напрямую.
>> Мне кажется нет никакой разницы через переходник оно или нет если надо
>> ждать ответа от устройства "на том конце" и единственный путь определить
>> что его там нет - отвал по таймауту.
> Не могу понять откуда 30секунд таймаута, делал так stty -F /dev/ttyS4 -icanon
> min 0 time 3, все равно 30 секЭто полное время работы скрипта? Потому что момент когда вы определяете занят порт или нет- имеет задержку 1 секунда.
То есть весь последующий код - выполняется (или не должен выполнятся) через 1 секунду после того как вы обнаружили что "порт пуст". Можно предположить что ваша проверка пуст ли порт- некорректна, и последующий 30 секундный таймаут- результат того что на пустом порту отрабатывает вот тот весь остальной код.
>>>> Воткни принтер через переходник 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что изменилось не пойму