Wie führt man in Bash oder Zsh für jeden Buchstaben, der in die Eingabeaufforderung eingegeben wird, eine Funktion aus?

Wie führt man in Bash oder Zsh für jeden Buchstaben, der in die Eingabeaufforderung eingegeben wird, eine Funktion aus?

ich weiss Bescheidpreexec()Hooks für zsh und wie dies in Bash erreicht werden kann. (Verknüpfung)

Aber kann ich dieStromeingangwährend Sie noch tippen?

Die Idee hinter dieser Frage ist folgende:

Um ein schnelleres Erlernen von Befehlen, Argumenten und Tastenkombinationen zu ermöglichen, möchte ich den eingegebenen Befehl in einer „Datenbank“ mit Hinweisen zu „Hilfe“, „Gut zu wissen“ und „Tastenkombinationen“ suchen und diese in einer anderen Sitzung mit Screen/TMUX anzeigen, während ich die andere eintippe.

Ist es möglich, den aktuell eingegebenen Befehl zu überprüfen? Wenn dies nicht bei jedem Tastendruck funktioniert, könnte auch eine Zeitschleife funktionieren.

Antwort1

Ich kann nur für die Fälle antworten zsh, in denen dies möglich ist: ja.

Erstens gibt es bereits einige Widgets fürinkrementelle Fertigstellung. Das erste ist offenbar das von Y. Fujii. Obwohlseine Websiteist auf Japanisch, Sie können also leicht herausfinden, wie es funktioniert und wie man es verwendet, auch ohne die Sprache zu sprechen. Auto-fuist eine Erweiterung des Originalskripts.

Soweit die Referenzen. In zshderzsh-Zeileneditor( zle) ist für die interaktive Nutzung der Kommandozeile zuständig. Neben vielen anderen Variablen, die Widgets zur Verfügung stehen (siehe man zshzle), sind diese für Sie von Interesse, da Sie dieaktuelle Befehlszeile:

$PUFFER: Der gesamte Inhalt des Bearbeitungspuffers.

$LBUFFER: Der Teil des Puffers, der links von der Cursorposition liegt.

$RBUFFER: Der Teil des Puffers, der rechts von der Cursorposition liegt.

Diese Variablen sind beschreibbar, was die aktuelle Befehlszeile ändert!

Um jeden Tastendruck zu erfassen, können Sie das Widget ändern self-insert, das (standardmäßig) für jeden Tastendruck außer LFoder ausgeführt wird CR. Hier ist ein Beispiel, das nichts wirklich Nützliches tut, aber für jeden Tastendruck einen Punkt anfügt $RBUFFER– nur um zu veranschaulichen, wie das funktioniert:

function self-insert() {
  RBUFFER+="."
  # execute some other command, but ensure they don't produce any output.
  zle .self-insert
  }
zle -N self-insert

.self-insertist das integrierte Widget, sodass wir nicht in eine Endlosschleife geraten.

Sie können also entweder von vorne beginnen oder Fujiis Skript verwenden und es ändern. Ein Vorteil des letzteren ist, dass es auch einige Löschvorgänge für Tastenanschläge übernimmt, die ich hier vernachlässigt habe.

Antwort2

Für Bash können Sie folgendes test.shSkript erstellen:

#!/usr/bin/env bash

ARRAY=('1' '2' '3' '4' '5' '6' '7' '8' '9' '0' '-' '=' 'BACKSPACE' ''
'q' 'w' 'e' 'r' 't' 'y' 'u' 'i' 'o' 'p' '[' ']' 'NEWLINE' '' 
'a' 's' 'd' 'f' 'g' 'h' 'j' 'k' 'l' ';' "'" '' '' '' 'z' 'x' 'c' 
'v' 'b' 'n' 'm' '0' ',' '.' '/' '' '' 'SPACE')

while read row 
do
    if [[ "$row" == *press* ]]
    then
        index=$((${row/key press   /}-10))
        if [[ "${ARRAY[$index]}" == 'NEWLINE' ]] 
        then
                printf "\n"
        elif [[ "${ARRAY[$index]}" == 'BACKSPACE' ]] 
        then
            echo  -ne "\b \b"
        elif [[ "${ARRAY[$index]}" == 'SPACE' ]] 
        then
            printf " "
        else
            printf "%s" "${ARRAY[$index]}"
        fi
    fi
done

Es handelt sich um ein einfaches Skript, das einige Tastaturcodes empfängt und auf dem Bildschirm ausgibt. Übergeben Sie ihm nun die Tastaturcodes:

$ stdbuf -o0 xinput test 'AT Translated Set 2 keyboard' | bash test.sh

Wenn Sie jetzt in ein anderes Terminal tippen, sollte es Tastenwerte empfangen. Ich weiß nicht, ob es eine clevere Möglichkeit gibt, Tastencodes ihren ASCII-Werten zuzuordnen, also mache ich nur eine einfache Zuordnung. Sie können diesen Code verbessern, damit er auch auf andere Tasten reagiert. Beachten Sie jedoch, dass das Skript alle Tastatureingaben empfängt und nicht nur an ein bestimmtes Terminal weiterleitet.

Was die Aufgabe selbst betrifft (Überprüfung des aktuell eingegebenen Befehls), können Sie compgen -cbasierend auf dem übergebenen Argument eine Liste möglicher Vervollständigungen generieren:

 $ compgen -c 'ls' | head -1
 ls
 $ compgen -c 'lsp' | head -1
 lspci

verwandte Informationen