GNU/Linux >> Linux Esercitazione >  >> Linux

Come rilevare la pressione dei tasti su un terminale Linux, stile di basso livello in Python

Per impostazione predefinita, l'input standard è bufferizzato e utilizza la modalità canonica. Ciò consente di modificare l'input. Quando premi il tasto Invio, l'input può essere letto da Python.

Se vuoi un accesso di livello inferiore all'input puoi usare tty.setraw() sul descrittore di file di input standard. Questo ti permette di leggere un carattere alla volta usando sys.stdin.read(1) . Nota che in questo caso lo script Python sarà responsabile della gestione dei caratteri speciali e perderai alcune delle funzionalità come l'eco dei caratteri e l'eliminazione. Per maggiori informazioni dai un'occhiata a termios(3).

Puoi leggere le sequenze di escape utilizzate per i tasti su e giù su Wikipedia.

Dovresti essere in grado di replicare il comportamento standard della shell se gestisci tutto in un unico processo.

Potresti anche provare a usare un sottoprocesso (non riferito al modulo - puoi usare fork() o popen() ). Dovresti analizzare l'input non bufferizzato nel processo principale e inviarlo allo stdin (che può essere bufferizzato) del sottoprocesso. Probabilmente avrai bisogno di una comunicazione tra processi per condividere la cronologia con il processo principale.

Ecco un esempio del codice necessario per acquisire l'input in questo modo. Nota che sta eseguendo solo un'elaborazione di base e necessita di più lavoro per adattarsi al tuo caso d'uso.

import sys
import tty
import termios


def getchar():
    fd = sys.stdin.fileno()
    attr = termios.tcgetattr(fd)
    try:
        tty.setraw(fd)
        return sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSANOW, attr)


EOT = '\x04'  # CTRL+D
ESC = '\x1b'
CSI = '['

line = ''

while True:
    c = getchar()
    if c == EOT:
        print('exit')
        break
    elif c == ESC:
        if getchar() == CSI:
            x = getchar()
            if x == 'A':
                print('UP')
            elif x == 'B':
                print('DOWN')
    elif c == '\r':
        print([line])
        line = ''
    else:
        line += c

Python ha un modulo tastiera con molte funzionalità. Installalo, magari con questo comando:

pip install keyboard

quindi usalo nel codice come questo:

import keyboard

keyboard.add_hotkey('up', lambda: keyboard.write('write command retrieved from the history of your shell here'))
keyboard.wait('esc')

oppure potresti usare la funzione on_press_keyUsing the function on_press_key:

keyboard.on_press_key("p", lambda _:print("You pressed p"))

Ha bisogno di una funzione di callback. Ho usato _ perché la funzione della tastiera restituisce l'evento della tastiera a quella funzione.

Una volta eseguito, eseguirà la funzione quando viene premuto il tasto. Puoi fermare tutti gli hook eseguendo questa riga:

keyboard.unhook_all()

per informazioni dettagliate puoi vedere un post simile su StackOverflow, spero che questo aiuti a rilevare la pressione dei tasti in Python?

Nota laterale: hai menzionato il metodo fork() sopra In python possiamo usare il

processo secondario modulo integrato qui, quindi importa sottoprocesso e siamo a posto. La funzione run in particolare viene utilizzata qui per eseguire comandi in una subshell. Per coloro che provengono da C, questo ci evita di andare a fare il fork e creare un processo figlio e quindi aspettare che il figlio finisca l'esecuzione, lascia che Python se ne occupi questa volta.

codice di esempio per eseguire i comandi inseriti dall'utente

def execute_commands(command):
    try:
        subprocess.run(command.split())
    except Exception:
        print("psh: command not found: {}".format(command))

Linux
  1. Come installare Python su Linux

  2. Simulazione dell'evento Key Press utilizzando Python per Linux

  3. Come posso ottenere lo stato della tastiera in Linux?

  4. Come eseguire il file python in linux

  5. Come disabilitare un tasto della tastiera in Linux (Ubuntu)?

Come controllare lo stato della batteria del laptop e il livello nel terminale in Linux

Come aprire una finestra di un terminale Linux

Come creare una passphrase chiave SSH in Linux

Come confrontare due file nel terminale Linux

Come aprire un PDF in un terminale Linux

Come abilitare la modalità grafica bassa in Ubuntu Linux