【问题标题】:RPi - Python Curses program running at boot does not have keyboard focusRPi - 在启动时运行的 Python Curses 程序没有键盘焦点
【发布时间】:2019-01-06 19:46:08
【问题描述】:

我正在尝试编写一个程序,该程序将在我的树莓派启动时运行,并允许我立即开始用我的键盘输入内容并让它被程序拾取。我不想在 pi 启动时手动启动程序。我需要使用 curses(或类似的无缓冲键盘输入库),因为我在 2x16 I2C LCD 上显示我正在输入的内容,但我还需要将我输入的所有内容记录到文本文件中。

现在,我通过在 rc.local 中添加一行来在启动时自动启动程序。这有效,I2C 显示器正确显示程序输出,但它不响应键盘输入,而是在奇怪的控制台上显示键盘输入(当我将饼图连接到屏幕时,目标是无头运行)当我按下回车键并说 -bash: 'whatever I just typed' command not found 时退出的布局。

我已经试过了:

  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 python-3.x raspberry-pi python-curses


    【解决方案1】:

    好的,实际上我所要做的(在对 stackexchange 进行更多研究后发现,this 是包含我正在寻找的答案的线程)是从 ~/.bashrc 而不是 /等/rc.local。这种方法效果很好,正是我想要的。

    【讨论】:

      【解决方案2】:

      这应该是因为你调用程序的方式:

      python3 journal.py &
      

      您可能需要查看 bash(或您的 shell)手册页的 JOB CONTROL

      只有前景 允许进程从……终端读取。后台进程 尝试从...读取 内核终端向终端发送 SIGTTIN ... 信号 驱动程序,除非被捕获,否则会暂停进程。

      简而言之,一旦 curses(或任何与此相关的)尝试从 stdin 读取,您的进程可能会停止(在它可能已经写入您的显示器之后)。将其保留在前台以便能够使用stdin(以及通过扩展键盘)。

      旁注:在您的情况下不确定rc.local 的发行版和实现细节,但初始化脚本通常不是已经使用uid/gid 0 运行(不通过sudo 包装单个调用?)

      【讨论】:

      • 我将致力于研究作业控制并尝试找到解决方法。你有什么技巧可以让我的 python 程序保持在前台,而无需手动输入和运行脚本吗?关于您的旁注的主题,我不知道是否需要将 sudo 放在 init 命令中,我只是这样做是因为我认为它可能需要它才能工作,尽管我对 linux 的了解不够多,不知道是否我需要与否。我很可能不会。
      • 想到的最快方法:删除&,如果您可以留在rc.local 本地直到脚本完成。您实际上真的不希望后台进程(不在当前控制台的前台)继续从您的键盘获取输入,这会引发许多(也是安全)问题。
      • 我已经尝试删除 &,但是当我这样做时,我的 pi 永远不会在主显示输出上完全启动(我必须通过 SSH 进入它并更改 rc.local 的代码才能让 pi 启动再次完全)。它在“启动主机名服务”行之后卡住了。
      • “从不完全启动”我想是指getty(或类似的)没有启动?您是否希望系统启动getty / 显示登录提示并且键盘对您的应用程序和登录提示都可用?或者运行您的应用程序而不是登录提示?不幸的是,所有这些都是特定于发行版的。我可以看到更新rc.local(甚至rc.Src.M)是一个选项(在我的系统上)。否则/etc/inittab 也可能很有趣。基于 systemd 的系统将再次以不同方式配置(我不熟悉)。
      • 感谢您的帮助,我会调查这些事情。
      猜你喜欢
      • 2018-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-11
      • 2016-03-28
      相关资源
      最近更新 更多