На одном из форумов мне порекомендовали написать скрипт и даже помогли с написанием. Вот этот скрипт:
#! /bin/bash
SCANNER=`sane-find-scanner -q | sed -e 's/.*at /snapscan:/'` #Определяем активный первый попавшийся ЮСБ сканнер
TMPFILE="/tmp/scan.tiff" # временный файл куда сканируем
LOCKFILE="/tmp/copy.lock" #Файл блокировки
#Проверяем не запущена ли программа
#и создаем файл блокировки, чтобы случайно не запустить вторую копию
if ! lockfile-create --retry 2 -l $LOCKFILE; then
exit
fi
scanimage --device-name $SCANNER --format tiff --mode Gray -x 210 -y 297 --resolution 300 --brightness -3 -p > $TMPFILE
#Сканируем. Параметры сканирования смотрите в man scanimage
tiff2ps -z -w 8.27 -h 11.69 $TMPFILE | lp
lockfile-remove -l $LOCKFILE #удаляем файл блокировки
Прикручиваем интерфейс
У вышеуказанного скрипта был огромный недостаток — нельзя было указать количество копий. После небольшой переделки стало возможным указывать в командной строке количество копий, но это не устроило моих домочадцев, которые не желали лезть в консоль. Писать нативное приложение с интерфейсом я не хотел и не умел. Потом я узнал, что к bash скриптам можно прикрутить интерфейс через программы dialog, zenity, kdialog. Ну я попробовал переписать используя zenity + я добавил обработку различных ошибок. Оказалось добавление интерфейса не просто, а очень просто! Вот что из этого у меня вышло.
Сначала определяем переменные и блокируем.
SCANNER=`sane-find-scanner -q | sed -e 's/.*at /snapscan:/'` #Определяем активный первый попавшийся ЮСБ сканнер
DIALOG=zenity
TMPFILE="/tmp/scan.tiff" # временный файл куда сканируем
LOCKFILE="/tmp/copy.lock" #Файл блокировки
DLG_COUNT_TITLE="Количество копий"
DLG_COUNT_TEXT="Установите необходимое количество копий"
DLG_PROGRESS_TITLE="Процесс копирования"
DLG_PROGRESS_TEXT="Выполняю..."
MSG_START_PROCESS="Начинаю копирование со сканера $SCANNER"
MSG_SCAN="Сканирую"
MSG_PRINT="Отправка задания на печать"
MSG_COMPLETE="Задание отправлено на печать."
MSG_ERROR_LOCK="Ошибка: запущена другая копия программы, дождитесь пока программа закончит работу или закройте его."
MSG_ERROR_SCAN="Ошибка: не получилось сканировать, скорее всего сканер занят другим приложением или сканер не подключен."
MSG_ERROR_PRINT="Ошибка: не получилось распечатать."
После инициализации всех переменных скрипт спрашивает количество копий. Результат программа возвращает в консоль, но мы с помощью обратных одиночных кавычек (там где находиться русское «ё», но в английской раскладке) присваиваем результат переменной COPY_COUNT.
COPY_COUNT=`$DIALOG --scale\
--title="$DLG_COUNT_TITLE"\
--text="$DLG_COUNT_TEXT"\
--min-value=1\
--max-value=50\
--value=1\
--step=1`
Zenity возвратить код возврата, которая храниться в переменной $?.. Мы должны будем проверить его. Коды возврата: 0 — пользователь указал/ввел что то и нажал ОК; 1 — пользователь нажал «Отмена»; -1 — произошла ошибка. Целесообразно продолжать работу программы только при коде возврата 0, т.к. пользователь мог ошибочно запустить скрипт и у него должен быть выбор отмены.
if [[ "$?" == "0" ]]; then
#полезный код
fi
Так как процесс сканирования и печати достаточно «долгий» от нескольких секунд до нескольких минут, то надо как то показать на какой стадии идет процесс. При этом пользователь должен иметь возможность остановить процесс копирования на стадии сканирования. Для прогресс бара у zenity есть параметр --progress
. В результате предыдущий код приобретает вид:
if [[ "$?" == "0" ]]; then
(
#полезный код
) | $DIALOG --progress \
--title="$DLG_PROGRESS_TITLE" \
--text="$DLG_PROGRESS_TEXT" \
--percentage=0 --auto-close
fi
чтобы прогрессбар двигался, нужно чтобы в блоке отмеченным комментарием «полезный код» выводились значения процента через echo, например echo 10
установит прогрессбар на 10%, echo 100
на 100%. Чтобы указать на какой стадии процесса мы находимся (сканирование, печать или завершение программы) в виде текста надо тоже использовать echo, но при этом мы должны добавить знак решетки в начале сообщения например echo “#Идет процесс сканирования” заставит вывести текст на прогресс баре.
И на последок уже добавляем команды сканирования и печати.
Заключение
В результате получилась программа которая имеет очень простой и понятный интерфейс и функционал не уступающей родной программе копирования от Epson.
#! /bin/bash
SCANNER=`sane-find-scanner -q | sed -e 's/.*at /snapscan:/'` #Определяем активный первый попавшийся ЮСБ сканнер
DIALOG=zenity
TMPFILE="/tmp/scan.tiff" # временный файл куда сканируем
LOCKFILE="/tmp/copy.lock" #Файл блокировки
DLG_COUNT_TITLE="Количество копий"
DLG_COUNT_TEXT="Установите необходимое количество копий"
DLG_PROGRESS_TITLE="Процесс копирования"
DLG_PROGRESS_TEXT="Выполняю..."
MSG_START_PROCESS="Начинаю копирование со сканера $SCANNER"
MSG_SCAN="Сканирую"
MSG_PRINT="Отправка задания на печать"
MSG_COMPLETE="Задание отправлено на печать."
MSG_ERROR_LOCK="Ошибка: запущена другая копия программы, дождитесь пока программа закончит работу или закройте его."
MSG_ERROR_SCAN="Ошибка: не получилось сканировать, скорее всего сканер занят другим приложением или сканер не подключен."
MSG_ERROR_PRINT="Ошибка: не получилось распечатать."
#Проверяем не запущена ли программа
if ! lockfile-create --retry 2 -l $LOCKFILE; then
$DIALOG --error --text "$MSG_ERROR_LOCK"
exit
fi
COPY_COUNT=`$DIALOG --scale\
--title="$DLG_COUNT_TITLE"\
--text="$DLG_COUNT_TEXT"\
--min-value=1\
--max-value=50\
--value=1\
--step=1`
if [[ "$?" == "0" ]]; then
(
echo "# $MSG_START_PROCESS"
echo "10"
sleep 2
echo "# $MSG_SCAN"
echo "25"
#Сканируем. Параметры сканирования смотрите в man scanimage
scanimage --device-name $SCANNER\
--format tiff\
--mode Gray\
-x 210 -y 297 --resolution 300\
--brightness -3 > $TMPFILE
if [ $? != 0 ]; then
$DIALOG --error --text "$MSG_ERROR_SCAN"
lockfile-remove -l $LOCKFILE
exit
fi
echo "# $MSG_PRINT"
echo "75"
#Проверяем количество копий и печатаем
if [[ "$COPY_COUNT" == "1" ]]; then
tiff2ps -z -w 8.27 -h 11.69 $TMPFILE | lp
else
tiff2ps -z -w 8.27 -h 11.69 $TMPFILE | lp -n $COPY_COUNT
fi
if [ $? != 0 ]; then
$DIALOG --error --text "$MSG_ERROR_PRINT"
lockfile-remove -l $LOCKFILE
exit
fi
rm -f $TMPFILE
echo "# $MSG_COMPLETE"
echo "100"
sleep 2
) | $DIALOG --progress\
--title="$DLG_PROGRESS_TITLE"\
--text="$DLG_PROGRESS_TEXT"\
--percentage=0\
--auto-close || lockfile-remove -l $LOCKFILE
fi
lockfile-remove -l $LOCKFILE
Надеюсь мой скрипт окажется полезным для вас.