RPi - программа Python Curses, запущенная при загрузке, не имеет фокуса клавиатуры

1

Я пытаюсь написать программу, которая будет запускаться при запуске моего raspberry pi и позволит мне сразу же начать набирать текст на клавиатуре, и она будет подхвачена программой. Я не хочу вручную запускать программу при запуске пи. Мне нужно использовать curses (или аналогичную небуферизованную библиотеку ввода с клавиатуры), потому что я отображаю то, что я печатаю, на ЖК-дисплее 2x16 I2C, но мне также нужно, чтобы все, что я печатаю, записывалось в текстовый файл.

Прямо сейчас я автоматически запускаю программу при загрузке, помещая строку в rc.local. Это работает, и дисплей I2C правильно отображает вывод программы, но он не реагирует на ввод с клавиатуры, и вместо этого отображается ввод с клавиатуры (когда я подключаю круговую диаграмму к экрану, цель состоит в том, чтобы запустить безголовый) на странной консоли раскладка, которая завершается, когда я нажимаю клавишу ввода и говорит -bash: команда "все, что я только что набрал" не найдена.

Я уже попробовал:

  1. Установка таймера в начале программы для ожидания полной загрузки pi перед инициализацией окна curses и захвата клавиатуры

  2. Создание отдельной программы на Python для ожидания полной загрузки pi и последующего запуска основного сценария путем его импорта.

Хотя ни один из этих методов не работает, я получаю ту же проблему с небольшими отличиями.

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

Мой код:

 #!/usr/bin/python
import I2C_LCD_driver, datetime, sys
from time import *
from subprocess import call

mylcd = I2C_LCD_driver.lcd()

for x in range(30): #waits for raspberry pi to boot up
    mylcd.lcd_display_string("Booting Up: "+str(x), 1)
    sleep(1)

import curses
key = curses.initscr()
curses.cbreak()
curses.noecho()
key.keypad(1)
key.nodelay(1)

escape=0
while escape==0:
    #variable initialization

    while 1:
        k=key.getch()
        if k>-1: #runs when you hit any key. getch() returns -1 until a key is pressed
            if k==27: #exits the program when you hit Esc
                break
            elif k==269:
                # a couple other special Function key cases are here
            else:
                inpt=chr(k)
                mylcd.lcd_display_string(inpt,2,step) #writes the last character to the display
                #some more code that handles writing the text to the LCD, which works flawlessly when run manually.

    file.write("%s\r\n" % entry)
    file.close()
    mylcd.lcd_display_string("Saved           ",2)
    mylcd.lcd_display_string("F1 New F2 PwrOff",1)
    while 1:
        k=key.getch()
        if k>-1:
            if k==265: #do it again! with F1
                mylcd.lcd_clear()
                break
            elif k==266: #shut down with F2
                escape=1
                break
curses.nocbreak()
key.keypad(0)
curses.echo()
curses.endwin()
call("sudo shutdown -h now", shell=True)

Строка, которую я имею в /etc/rc.local, выглядит следующим образом, если это важно:

sudo python3 journal.py &

за ним следует строка "exit 0". Спасибо за любую помощь, которую вы можете предоставить. Я знаю, что это очень специфическая проблема, и воспроизвести ее будет утомительно, но если кто-нибудь знает что-либо об функциях автозапуска, я буду очень признателен за любые советы.

Теги:
python-3.x
raspberry-pi
python-curses

2 ответа

0
Лучший ответ

Хорошо, буквально все, что мне нужно было сделать (что я нашел после нескольких исследований стекового обмена, это поток, содержащий ответ, который я искал), - запустить мою программу из ~/.bashrc вместо /etc/rc.local, Этот метод работает отлично, именно то, что я хотел.

0

Это должно быть из-за того, как вы назвали программу:

python3 journal.py &

Вы можете проверить JOB CONTROL справочной страницы bash (или вашей оболочки):

Только процессы переднего плана могут читать из... терминала. Фоновые процессы, которые пытаются читать из... терминала, посылают сигнал SIGTTIN... драйвером терминала ядра, который, если не перехвачен, приостанавливает процесс.

Короче говоря, однажды проклятия (или что-то в этом роде) попытаются прочитать со стандартного stdin, вероятно, ваш процесс остановлен (после того, как он, возможно, уже записан на ваш дисплей). Держите его на переднем плане, чтобы иметь возможность использовать стандартный stdin (и с помощью дополнительной клавиатуры).

Примечание: Не уверен насчет дистрибутива и деталей реализации rc.local в вашем случае, но разве скрипты init обычно не запускаются с uid/gid 0 (без переноса отдельных вызовов через sudo?)

  • 0
    Я буду работать над исследованием Job Control и попытаться найти обходной путь. Есть ли у вас какие-либо советы о том, как сохранить мою программу Python на переднем плане, не печатая и не запуская скрипт вручную? Что касается вашего примечания, я не знаю, нужно ли мне вводить sudo в команду init, я просто сделал это, потому что подумал, что это может понадобиться, хотя я не знаю достаточно о linux, чтобы знать, Мне это нужно или нет. Вполне вероятно, что я не.
  • 0
    Самый быстрый способ, который приходит на ум: Drop & если все нормально, оставайтесь в rc.local local, пока ваш скрипт не rc.local . Вы действительно не хотите, чтобы фоновые процессы (не на переднем плане текущей консоли) продолжали получать ввод с клавиатуры, что открывало массу проблем (в том числе и с безопасностью).
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню