GNU/Linux >> Znalost Linux >  >> Linux

Jak detekovat stisknutí kláves na linuxovém terminálu, nízkoúrovňový styl v pythonu

Ve výchozím nastavení je standardní vstup uložen do vyrovnávací paměti a používá kanonický režim. To vám umožní upravit váš vstup. Když stisknete klávesu enter, vstup může být přečten Pythonem.

Pokud chcete nižší úroveň přístupu ke vstupu, můžete použít tty.setraw() na standardním deskriptoru vstupního souboru. To vám umožní číst jeden znak po druhém pomocí sys.stdin.read(1) . Všimněte si, že v tomto případě bude skript Python zodpovědný za zpracování speciálních znaků a ztratíte některé funkce, jako je ozvěna a mazání znaků. Pro více informací se podívejte na termios(3).

O escape sekvencích, které se používají pro klávesy nahoru a dolů, si můžete přečíst na Wikipedii.

Pokud zvládnete vše v jednom procesu, měli byste být schopni replikovat standardní chování shellu.

Můžete také zkusit použít podproces (nevztahující se na modul – můžete použít fork() nebo popen() ). Vstup bez vyrovnávací paměti byste analyzovali v hlavním procesu a odeslali jej do stdin (který lze uložit do vyrovnávací paměti) podprocesu. Pravděpodobně budete potřebovat nějakou meziprocesovou komunikaci, abyste mohli sdílet historii s hlavním procesem.

Zde je příklad kódu potřebného k zachycení vstupu tímto způsobem. Všimněte si, že provádí pouze základní zpracování a potřebuje více práce, aby vyhovoval vašemu případu použití.

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 má modul klávesnice s mnoha funkcemi. Nainstalujte jej, možná pomocí tohoto příkazu:

pip install keyboard

pak jej použijte v kódu takto:

import keyboard

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

nebo můžete použít funkci on_press_keyPomocí funkce on_press_key:

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

Potřebuje funkci zpětného volání. Použil jsem _, protože funkce klávesnice vrací událost klávesnice této funkci.

Po provedení se funkce spustí po stisknutí tlačítka. Všechny háčky můžete zastavit spuštěním tohoto řádku:

keyboard.unhook_all()

pro podrobné informace můžete vidět podobný příspěvek na stackoverflow, doufám, že to pomůže zjistit stisknutí klávesy v pythonu?

Na straně Poznámka: výše zmíněnou metodu fork() V pythonu můžeme použít

dílčí proces vestavěný modul zde, takže importujte podproces a můžeme začít. K provádění příkazů v subshell se zde používá zejména funkce run. Pro ty, kteří přicházejí z C, nás to ušetří, abychom nemuseli dělat větvení a vytvářet podřízený proces a pak čekat, až dítě dokončí provádění, tentokrát nechejte Python, aby se o to postaral.

ukázkový kód pro provedení příkazů zadaných uživatelem

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

Linux
  1. Jak nainstalovat Python 3.10 na Rocky Linux 8

  2. Jak vytvořit slovník Python

  3. Jak mohu získat stav klávesnice v Linuxu?

  1. Jak nainstalovat Python na Linux

  2. Jak spustit soubor python v linuxu

  3. Jak deaktivovat klávesu klávesnice v Linuxu (Ubuntu)?

  1. Simulace události Key Press pomocí Pythonu pro Linux

  2. Jak vložit do terminálu linux ve virtuální krabici s klávesnicí Mac?

  3. Jak provedu I/O nízké úrovně na souboru zařízení Linux v Pythonu?