Системный звуковой сигнал из rc.local-запланированного сценария Python

Мне удалось создать сценарий Python для принятия магнитных проведений карты от основанного на USB читателя. Это, кажется, работает как ожидалось. Часть стандартной программы является вихревой командой для продвижения данных к другому серверу. Так как сервер Ubuntu не будет иметь монитора/клавиатуры/мыши, мой единственный способ ответить пользователю со звуком от докладчика сервера.

Обычно, вихревая команда получает стандартные 200 ответов от другого сервера приложений. Иногда, однако, это получает 500 ошибочных ответов, и я должен передать что-то назад пользователю, чтобы предупредить их, которые "на этот раз не работали, просканируйте свою карту снова".

Простой механизм должен подать звуковой сигнал однажды для успеха и ничего для отказа. Как записано и выполнено от терминала, это работает. Как запланировано от rc.local, системный звуковой сигнал не звучит.

...
args = 'card=' + trackone.group(2)
r = requests.get('http://apiserver/api/', args)
if r.status_code == 200:
    # First attempt which doesn't work from rc.local
    # print("\a")
    # Second attempt, wrap the beep in a shell script
    os.system("sh /home/myuser/beep.sh")
else
    print(r.status_code)

И я попытался создать простой сценарий оболочки beep.sh:

#!/bin/bash
echo "\a"

Как упомянуто, обе попытки работают от терминала, но не, как выполнено от корня под управлением rc.local. И я знаю, что API называют, так как я вижу записи в журнале.

Строка в rc.local похожа на это:

python '/home/myuser/scancards.py'

Существует ли способ позволить этой команде - как выполнено в рамках процесса init.d - мочь подать звуковой сигнал динамик?

2
задан 13 October 2016 в 00:29

4 ответа

Звуковой сигнал установки с sudo apt install beep (используют склонный - добирается вместо Кв. для более ранних версий, чем 16,04)

, Так как звуковой сигнал поддерживает различные частоты, Вы могли просто beep -f "$r.statuscode" or beep once for yes звуковой сигнал-r1and twice for no звукового сигнала-r2'.

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

Примеры:

номер: beep -f 250

Да: beep -f 2500

Да, я знаю, что это - короткий ответ, но иногда это - все, что требуется.

дальнейшее исследование указывает, что необходимо будет прокомментировать черный список pcspkr в/etc/modprobe.d/blacklist.conf, чтобы заставить это работать. Вам, вероятно, также придется установить suid, обдумал звуковой сигнал, чтобы заставить это работать (я использовал sudo chmod 4755 /usr/bin/beep, поскольку у меня нет опасений по поводу других, играющих со звуковым сигналом в этой системе), можно хотеть использовать группы для корректировки полномочий так, чтобы только достойные пользователи могли выполнить звуковой сигнал.

Примечание: Как @JdeBP указывает в его ответе, который Вы можете иметь к , открывают дескриптор файла для оконечного устройства

Источники: man beep

Получение динамика компьютера подать звуковой сигнал

http://pubs.opengroup.org/onlinepubs/9699919799/

2
ответ дан 2 December 2019 в 02:49

Для подачи звукового сигнала динамика компьютера из сценария Python Вы могли использовать Linux evdev API:

#!/usr/bin/env python
import ctypes
import math
import os
import time


EV_SND = 0x12  # linux/input-event-codes.h
SND_TONE = 0x2  # ditto
time_t = suseconds_t = ctypes.c_long

class Timeval(ctypes.Structure):
    _fields_ = [('tv_sec', time_t),       # seconds
                ('tv_usec', suseconds_t)] # microseconds

class InputEvent(ctypes.Structure):
    _fields_ = [('time', Timeval),
                ('type', ctypes.c_uint16),
                ('code', ctypes.c_uint16),
                ('value', ctypes.c_int32)]


frequency = 440  # Hz, A440 in ISO 16
device = "/dev/input/by-path/platform-pcspkr-event-spkr"
pcspkr_fd = os.open(device, os.O_WRONLY)  # root! + modprobe pcspkr
fsec, sec = math.modf(time.time())  # current time
ev = InputEvent(time=Timeval(tv_sec=int(sec), tv_usec=int(fsec * 1000000)),
                type=EV_SND,
                code=SND_TONE,
                value=frequency)
os.write(pcspkr_fd, ev)  # start beep
try:
    time.sleep(0.2)  # 200 milliseconds
finally:
    ev.value = 0  # stop
    os.write(pcspkr_fd, ev)

Выполнение beep-evdev.py как корень. /etc/rc.local выполняется корнем, и поэтому сценарий должен работать, как.

, Если файл /dev/input/by-path/platform-pcspkr-event-spkr не делает, существует, удостоверьтесь, что pcspkr модуль загружается:

root# modprobe pcspkr

сценарий не имеет никаких других зависимостей за исключением python сам.

0
ответ дан 2 December 2019 в 02:49

как выполнено в рамках процесса init.d

Нет такой вещи как "init.d процесс".

rc.local часть rc система, которая была заменена три раза. Та система была заменена van Smoorenburg rc, выскочка (десятилетие назад), и (с версии 15 Ubuntu) systemd. То, что Вы используете, является третьим повторением назад контейнер совместимости.

В systemd операционных системах, таких как версии Ubuntu 15 и позже, контейнер является systemd сервисом, названным rc-local.service. Можно узнать его сервисное определение с

systemctl cat rc-local.service

Как Вы видите, это не определяется как присоединение сервиса к оконечному устройству. Сервисный процесс не выполняется с терминалом управления, и его стандартный ввод и вывод не подключен к терминалу.

Тот код Python и сценарий оболочки "не подают звуковой сигнал динамик компьютера". Они пишут символьный № 7 в свои стандартные выводы. Это именно так происходит при выполнении их в интерактивном режиме на сессии входа в систему, что устройство, которое является их стандартным выводом, интерпретирует символьный № 7 как инструкцию шуметь. Перенаправьте стандартный вывод интерактивной команды к /dev/null и наблюдайте, как тихий код становится.

Который является почему то, что rc.local (очень) назад контейнер совместимости не имеет никакого соединения с оконечным устройством, важно.

Можно решить это с beep утилита. Это пытается (если вызвано соответственно) явно открыть дескриптор файла для оконечного устройства и отправить символьный № 7 в (или консоль использования или evdev ioctl()s на), что устройство вместо того, чтобы просто предположить, что стандартный вывод является оконечным устройством.

Но это стоит думать трудно о не использовании rc.local, также.

Дальнейшее чтение

1
ответ дан 2 December 2019 в 02:49

Подавать звуковой сигнал динамик компьютера от /etc/rc.local Сценарий Python через консоль Linux, Вы могли использовать console_ioctl(4): KDMKTONE, KIOCSOUND:

#!/usr/bin/env python
import os    
from fcntl import ioctl

CLOCK_TICK_RATE = 1193180 # magic https://github.com/johnath/beep/blob/0d790fa45777896749a885c3b93b2c1476d59f20/beep.c#L31-L49
KDMKTONE = 0x4B30   # generate tone include/uapi/linux/kd.h#L25

def beep(console_fd, frequency=440, length_millis=200):
    period = CLOCK_TICK_RATE // frequency
    ioctl(console_fd, KDMKTONE, (length_millis << 16) | period) # start beeping
    # return immediately

beep(console_fd=os.open('/dev/tty0', os.O_RDONLY | os.O_NOCTTY)) # I'm [G]root

Посмотрите beep.py. Это работает потому что /etc/rc.local выполняется root. Можно выполнить его как обычный пользователь при владении терминалом, например, в виртуальной консоли Ctrl+Alt+F1 (нажмите Alt+F7 для переключения назад в менеджер окон GUI).

Удостоверьтесь это pcspkr модуль ядра не помещен в черный список (прокомментируйте значение по умолчанию):

$ sudo sed -i 's/^blacklist pcspkr/#blacklist pcspkr/' /etc/modprobe.d/blacklist.conf

Удостоверьтесь, что это может быть загружено без любых ошибок:

$ sudo modprobe pcspkr

Удостовериться /etc/rc.local исполняемый файл:

$ sudo chmod +x /etc/rc.local

print('\a') (запись U+0007 BELL* символ к stdout), приводит к разным вещам в зависимости от Вашей среды.

Это может играть bell.ogg образец загрузил использование pactl команда (для PulseAudio звучат как сервер):

$ pactl upload-sample /usr/share/sounds/ubuntu/stereo/bell.ogg bell.ogg

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


В моей системе Ubuntu 16.04, print('\a') от /etc/rc.local записи #007 кому: /var/log/syslog и звуковые сигналы динамик компьютера (systemctl cat rc-local.service шоу StandardOutput=journal+console т.е. вывод переходит к файлу журнала и консоли).

0
ответ дан 2 December 2019 в 02:49

Другие вопросы по тегам:

Похожие вопросы: