[РЕШЕНО] Помогите склепать скрипт!

Автор }{ronoTrigger, 07 июня 2014, 13:51:04

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

}{ronoTrigger

Я, как новый пользоваель GNU Linux прошу помощи у сообщества. Ситуация такая.
скрипт примерно такой:

#!/bin/bash
echo "Привет форумчане! Прошу помощи в написании скрипта." | RHVoice | aplay

привязываю данный скрипт к клавише (5) на клавиатуре с помощью xbindkeys. Давим кнопку 5 и слышим сообщение. Пол-дела уже есть и то хорошо. Но дальше хуже. Юзер давит на кнопку 2-3 секунды .... эффект незамедлительно сказывается - запущщен скрипт в N--> бесконечности экземплярах.
1. Каким образом разрешить запускать только один процесс?

пробовал отключать клаву:

$ xinput --list | grep AT
↳ AT Translated Set 2 keyboard    id=12   [slave keyboard (3)]
$ xinput --list-props 12
Device 'AT Translated Set 2 keyboard':
    Device Enabled (139):   1
    Evdev Reopen Attempts (300):   10

в результате:
unlock:
/usr/bin/xinput --set-prop 12 139 1
lock:
/usr/bin/xinput --set-prop 12 139 0

Редактирую скрипт:

/usr/bin/xinput --set-prop 12 139 0
echo "Привет форумчане! Прошу помощи в написании скрипта." | RHVoice | aplay
/usr/bin/xinput --set-prop 12 139 1

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

2. Нужна кнопка "Стоп" - прекратить выполнение скрипта, т.к. текст может быть длинным и слушать его до конца не всем охота. Данная кнопка должна завершать не только этот скрипт, но и другие (подобные) скрипты.

О системе: Raspberry Pi, OS Raspbian (Debian)


Буду премного благодарен за оказанную помощь.

Alexey_F

Если нужен именно bash скрипт, то он тут нужен не один, т.к. управление производится через xbindkeys. Кстати, отключать клавиатуру не надо, достаточно сделать экспортированную переменную или lock-файл для отслеживания запуска скрипта-"проигрывателя".

Для того, чтобы отключать один или другие подобные скрипты, можно применять pkill или killall соответственно.

ZEN

#2
По идее, вот так должно работать:

#!/usr/bin/env bash
LOCK_FILE="/tmp/script.lock";

PID=$(pgrep -F $LOCK_FILE 2> /dev/null);

test -z $PID && {
    echo "Привет форумчане! Прошу помощи в написании скрипта." | RHVoice | aplay & PID=$!;
    echo $PID > $LOCK_FILE;
}

exit 0;


Если в данный момент процесс  с aplay (с прошлого запуска) не запущен, то он будет повторно запущен. В противном случае игнорируем запуск aplay.

Если нужно прибить процесс aplay, то делаешь другой скрипт

#!/usr/bin/env bash
LOCK_FILE="/tmp/script.lock";

PID=$(pgrep -F $LOCK_FILE 2> /dev/null);

test -z $PID && kill -9 "$PID" 2>/dev/null;

exit 0;
Crimea is Ukraine

}{ronoTrigger

Я извиняюсь, как новый пользователь GNU Linux я не совсем понимаю приведенный код

#!/usr/bin/env bash
LOCK_FILE="/tmp/script.lock";

PID=$(pgrep -F $LOCK_FILE 2> /dev/null);

test -z $PID && {
    echo "Привет форумчане! Прошу помощи в написании скрипта." | RHVoice | aplay & PID=$!;
    echo $PID > $LOCK_FILE;
}

exit 0;


в частности строка
LOCK_FILE="/tmp/script.lock"; # это файл блокировки, а script - это имя скрипта без расширения sh?
этот файл нужно создавать самому или он сам появится
не понятен скрипт, как это должно работать? Для меня это пока почти как китайская грамота, но я учусь.
Я уверен это интересно нужно не только мне

qupl

Цитата: }{ronoTrigger от 07 июня 2014, 20:28:30этот файл нужно создавать самому или он сам появится
этот код его создает-
echo $PID > $LOCK_FILE;

}{ronoTrigger

а вот PID=$! что делает?
echo "Привет, выпить нет?" | festival --language russian --tts & PID=$!;

ZEN

$! хранит ID процесса прошлой команды. По коду  выше в PID запишется код festival
Crimea is Ukraine

ZEN

Цитата: }{ronoTrigger от 07 июня 2014, 20:28:30не совсем понимаю приведенный код
Вот этот же код с комментарими
#!/usr/bin/env bash

# Файл блокировки в который будем записывать ID процесса
LOCK_FILE="/tmp/script.lock";

# pgrep считывает ID процесса из файла и проверяет
# есть ли такой ID в процессах
# Если есть, то в PID будет записан ID процесса
PID=$(pgrep -F $LOCK_FILE 2> /dev/null);

# Если PID не содержит ID процесса
test -z $PID && {
    # То заново запускаем процесс и сохраняем его ID в переменную PID
    echo "Привет форумчане! Прошу помощи в написании скрипта." | RHVoice | aplay & PID=$!;
    # Записываем PID в lock-файл
    echo $PID > $LOCK_FILE;
}

exit 0;

Crimea is Ukraine

}{ronoTrigger

Скрипт работает великолепно, в таком виде, чтение проходит один раз
#!/usr/bin/env bash
LOCK_FILE="/tmp/script.lock";
PID=$(pgrep -F $LOCK_FILE 2> /dev/null);
test -z $PID && {
    echo "Привет форумчане! Прошу помощи в написании скрипта." | RHVoice | aplay & PID=$!;
    echo $PID > $LOCK_FILE;
}
exit 0;


но как в него добавить еще несколько команд?
При попытке добавить
cat txt.txt | RHVoice | aplay
перед
echo "Привет форумчане! Прошу помощи в написании скрипта." | RHVoice | aplay & PID=$!;
гад читает оба сообщения вместе.
скрипт
#!/usr/bin/env bash
LOCK_FILE="/tmp/script.lock";
PID=$(pgrep -F $LOCK_FILE 2> /dev/null);
test -z $PID && kill -9 "$PID" 2>/dev/null;
exit 0;

процесс aplay не прибивает  :'( жаль, скрипт нужный. Либо я, что то не то делаю ...
Нужно срочно наверстывать знания, но как всегда проблема со временем

ZEN

#9
Попробуй вот так:
#!/usr/bin/env bash
LOCK_FILE="/tmp/script.lock";
PID=$(pgrep -F $LOCK_FILE 2> /dev/null);
test -z $PID && {
    cat txt.txt | RHVoice | aplay & PID=$!;
    echo $PID > $LOCK_FILE;
    wait || exit 1;
    echo "Привет форумчане! Прошу помощи в написании скрипта." | RHVoice | aplay & PID=$!;
    echo $PID > $LOCK_FILE;
    wait || exit 2;
}
exit 0;


Если все заработает как надо, то будем дальше мучать скрипт, который должен прибивать aplay
Crimea is Ukraine

}{ronoTrigger

Yes!!! Отлично!!! Работает. Не страшны ни двойные-тройные нажатия, ни долгосрочное давление на кнопку!
Осталось победить  aplay

ZEN

Проверь вот так скрипт для завершения работы aplay

#!/usr/bin/env bash
LOCK_FILE="/tmp/script.lock";
PID=$(pgrep -F $LOCK_FILE 2> /dev/null);
test -z $PID || kill -9 "$PID" 2>/dev/null;
exit 0;
Crimea is Ukraine

}{ronoTrigger

Сейчас всё сработало. Даже не могу в полной мере выразить благодарность.
Большое спасибо всем принявшим участие в решении проблемы.
ZEN, you're the best!

}{ronoTrigger

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

#!/usr/bin/bash
LOCK_FILE="/tmp/script.lock";
PID=$(pgrep -F $LOCK_FILE 2> /dev/null);
test -z $PID && {

# (Блок-1) Вступление
echo "Здравствуйте бла-бла-бла" | RHVoice | aplay & PID=$!;
echo $PID > $LOCK_FILE;
wait || exit 1;

# (Блок-2) Чтение полученного из внешнего источника текста
cat txt.txt | RHVoice | aplay & PID=$!;
echo $PID > $LOCK_FILE;
wait || exit 2;

# (Блок-3) Сообщение окончании информации и приглашение к дальнейшим действиям
echo "Конец текста, желаете получить новую информацию?" | RHVoice | aplay & PID=$!;
echo $PID > $LOCK_FILE;
wait || exit 3;
}
exit 0;


Скрипт для завершения работы aplay отрабатывает следующим образом:
1. Если чтение проходит в первом блоке и мы нажимаем клавишу вызова скрипта блокировки aplay - чтение прерывается и сразу начинается чтение Блока 2
2. Блок 2 имеет довольно большой обьём текста, и если пользователь понял, по началу текста, что ему данная информация не интересна, он вызывает скрипт-гаситель aplay
3. А теперь о плюшках, юзверь слыша зловещую тишину, решает получить новую инфу и тыркает на кнопку - процесс пошел! Но! примерно через 1-2 минуты в процессе получения важнейшей  :) для него инфы, параллельно, он слышит Блок-3 - Конец текста, желаете получить новую информацию?

Т.е. задержка (величина зависит от размеров текстовой инфы во 2-Блоке) может достигать до 3-х минут, что не есть хорошо.
Кто поделится инфой о причинах, а может и о путях устранения задержки. Сразу говорю, величина задержки составляет примерно 40% от времени прочтения голосом Блока-2
Увеличить мощность ЭВМ - не предлагать, привязан


Alexey_F

Разделить скрипт на части  по "блокам", сделать управляющий скрипт, гасить скрипт "блока"-2, а не aplay, не запускать новый "блок" до завершения любого другого.