RPi - программа Python Curses, запущенная при загрузке, не имеет фокуса клавиатуры
Я пытаюсь написать программу, которая будет запускаться при запуске моего raspberry pi и позволит мне сразу же начать набирать текст на клавиатуре, и она будет подхвачена программой. Я не хочу вручную запускать программу при запуске пи. Мне нужно использовать curses (или подобную небуферизованную библиотеку ввода с клавиатуры), потому что я отображаю то, что я печатаю, на ЖК-дисплее 2x16 I2C, но мне также нужно, чтобы все, что я печатаю, записывалось в текстовый файл.
Прямо сейчас я автоматически запускаю программу при загрузке, помещая строку в rc.local. Это работает, и дисплей I2C правильно отображает вывод программы, но он не реагирует на ввод с клавиатуры, а вместо этого отображается ввод с клавиатуры (когда я подключаю круговую диаграмму к экрану, цель состоит в том, чтобы запустить безголовый) на странной консоли раскладка, которая выходит, когда я нажимаю клавишу ввода, и говорит -bash: команда "что бы я только что набрал" не найдена.
Я уже попробовал:
Установка таймера в начале программы для ожидания полной загрузки pi перед инициализацией окна curses и захвата клавиатуры
Создание отдельной программы на 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". Спасибо за любую помощь, которую вы можете предоставить. Я знаю, что это очень специфическая проблема, и воспроизвести ее будет утомительно, но если кто-нибудь знает что-либо об функциях автозапуска, я был бы очень признателен за любые советы.
2 ответа
Хорошо, буквально все, что мне нужно было сделать (что я нашел после более подробного изучения stackexchange, это поток, содержащий ответ, который я искал), - запустить мою программу из ~/.bashrc вместо /etc/rc.local, Этот метод работает отлично, именно то, что я хотел.
Это должно быть из-за того, как вы назвали программу:
python3 journal.py &
Вы можете проверить JOB CONTROL справочной страницы bash (или вашей оболочки):
Только процессы переднего плана могут читать из... терминала. Фоновые процессы, которые пытаются читать из... терминала, посылают сигнал SIGTTIN ... драйвером терминала ядра, который, если не перехвачен, приостанавливает процесс.
Короче говоря, однажды проклятия (или что-нибудь в этом отношении) пытаются прочитать из stdin
Вероятно, ваш процесс остановлен (после того, как он уже записан на ваш дисплей). Держите его на переднем плане, чтобы иметь возможность использовать его stdin
(и по расширению клавиатуры).
Примечание: не уверен насчет дистрибутива и деталей реализации rc.local
в вашем случае, но не являются ли сценарии инициализации обычно уже запущенными с uid / gid 0 (без переноса отдельных вызовов через sudo
?)