ksh history-search-backward/forward

OsunSeyi

Well-Known Member
Gibt es in der Bash durch setzen von:

Code:
"\e[5~": history-search-backward
"\e[6~": history-search-forward

..in /etc/inputrc
Nun gibt es eine solche Datei aber nicht, mW könnte ich aber auch eine ~/.inputrc anlegen.

Ist eine derartige Konfiguration für die Ksh auch möglich?
Entschuldigt bitte, wenn ich "Löcher in den Bauch" frage...

Wohl habe ich Strg+R als Suchfunktion gefunden, aber das ist nicht annährend so praktisch.
 
Verknuepfe das mit bind (siehe manpage, da ist als Beispiel das history-per-cursor-tasten bei).

Das ist dann fuer emacs-mode ... just sayin.
 
Das werde ich probieren!
Habe etwas gefunden, was ich einigermaßen cool finde:

Code:
alias H="cat ~/.history | sort | uniq | fzf | tr '\n' ' ' | xsel"

Ich vermute, das ist mal wieder alles sehr dilletantisch. Aber funktioniert.
Zum Einfügen in die Konsole muß die mittlere Maustaste bemüht werden.

Dein Vorschlag werde ich auf jeden Fall befolgen! (bei mir braucht immer alles seine Zeit).
 
EDIT

Code:
alias  trim="tr '\n' ' ' | sed 's/^ *//g' | sed 's/ *$//g'"
alias     H="cat ~/.history | sort | uniq | fzf | trim | xsel"
 
Ein Tipp aus qualvoller Erfahrung: Ich würde nicht so viel mit Aliases machen, denn sie sind etwa "magisch" und in ihrer genauen Funktion nicht immer genau nachzuvollziehen. Ich würde stattdessen für alles, was über simples 'Ersetze Aufruf A durch Aufruf B' hinausgeht Funktionen definieren. Sie verhalten sich ebenfalls wie Shell-Kommandos, aber anders als bei Aliasen gibt es kaum Überraschungen und sie lassen sich fast unendlich komplex bauen.

Ohne das jetzt getestet zu haben könntest du zum Beispiel das hier machen:

Code:
trim() {
    tr '\n' ' ' $1 | sed 's/^ *//g' | sed 's/ *$//g'
}

Will man Funktionen definieren, die der Nutzer nicht benutzen soll, da sie nur für interne Aufgaben sind, ist die ungeschriebene Konvention ihre Namen mit _ beginnen zu lassen.
 
Vielen Dank für den Tip... und ein frohes Neues!

Ich weiß aber nicht so recht, wie man das anwendet.
Zwar benutze ich Funktionen innerhalb von Scripte, wenn sinnvoll, nicht aber außerhalb als Sammlung.

Dann würde ich für zB 'trim' eher ein eigenes kleines Script anlegen.

Und weil da allerhand zusammen kommt, sind in meinem 'bin' Verzeichnis viele Unterverzeichnisse, die mit 'find $HOME/bin -type d usw' in $PATH einbinde.

In meinen Scripten binde ich ein Script 'inc' ein (weil das so schön unauffällig ist), das zB Konsolefarben $hellrot ... $def zur Verfügung stellt und verschiedene Variablen. Es wäre warscheinlich auch der richtige Ort, um eine Funktionssammlung einzubinden.

Das dieses 'trim' jetzt als Alias definiert ist, hat damit zu tun, daß mit meinem Umzug auf OBSD auch eine Neusortierung von dem bisherigen Chaos dran ist.

Ist das eine rein organisatorische Frage, ob Schnipsel als Funktionssammlung oder eigene kleine Scripte vorliegen?

Will man Funktionen definieren, die der Nutzer nicht benutzen soll, da sie nur für interne Aufgaben sind, ist die ungeschriebene Konvention ihre Namen mit _ beginnen zu lassen.

Oki. Ich habe mal gehört, Variablenbezeichnungen sollten in klein gehalten werden, um nicht mit vom System verwendeten Variablen in die Quere zu kommen. Bin halt Laie. Wenn ich professionell angelegte Scripte zu Gesicht bekomme, kann ich sie in der Regel nicht mal 'lesen'.

Aber ich werde versuchen, mich daran zu halten!
 
Zuletzt bearbeitet:
So sieht es jetzt aus, ich finde es cool.
Ist ein eigenes kleines Script mit einem Shortcut in '~.alias':

Code:
#    https://www.baeldung.com/linux/remove-duplicate-lines-no-sorting

    hellcyan="\033[01;36m"
    def="\033[0m"

    PROG=`egrep -v '^ *((q)|(c)|(H)) *$' ~/.history     \
        | awk '!a[$0]++'                 \
        | tail -r                     \
        | fzf                         \
        | trim`

    if [ -n "$PROG" ] ; then

        echo -e -n $hellcyan $PROG [] $def
        read DOIT

#        ===================================
        if [ -z "$DOIT" ] ; then $PROG ; fi
#        ===================================
    fi
exit 0

Ja klar, so entspricht es halt meinem Niveau, aber es funktioniert.
Ach ja, 'trim' tut was es sagt, entfernt whitspace am Anfang und Ende.
 
Oki. Ich habe mal gehört, Variablenbezeichnungen sollten in klein gehalten werden, um nicht mit vom System verwendeten Variablen in die Quere zu kommen.
Du meinst kurz.
Das finde ich aber eher problematisch. Weil es ja auch viele kurze Befehle gibt. Die Chance das es da Kollisionen gibt ist entsprechend hoch.
Eigentlich ist es besser längere Namen zu benutzen (da kann man dann auch ein Unterstrich mit einbauen, weil das auch noch mal die Gefahr von Namenskollision verringert). Das hat dann auch gleichzeitig den Vorteil, das man aussagekräftige Namen nehmen kann die dann auch selbsterklärend sind.
Ansonsten geben ja auch Befehle wie set oder env Auskunft darüber, welche Variablen in Benutzung sind und welchen Wert die haben.

Ob die Bezeichnungmit einem Befehl/Programm kollidiert, kann man ja auch mit command prüfen:
Bash:
if command -v my_command; then
  echo "my_command is available"
else
  echo "my_command is not available"
fi

Ansonsten ist es zur Vermeidung von Namenskollision nicht verkehrt, mit Funktionen zu arbeiten. Dort kann man dann lokale Variablen (local) definieren die dann sozusagen in ihrem eigenen Namespace liegen:
Bash:
MY_VAR="Hello"

example_function() {
  local MY_VAR="World"
  echo $MY_VAR
}
echo $MY_VAR
example_function
echo $MY_VAR
ergibt:
Code:
Hello
World
Hello
Sprich die ursprüngliche Variable wird nicht angerührt, obwohl sie den gleichen Namen hat wie in der Funktion.

Ach ja, 'trim' tut was es sagt, entfernt whitspace am Anfang und Ende.
Man kann das übrigens auch mit Parameter-Expansion lösen und ist dann nicht mehr auf den Aufruf externer Programme angewiesen:
Bash:
# Nimmt Zeilen aus der Standardeingabe (stdin) entgegen
# und entfernt aus jeder Zeile führende und nachfolgende Leerzeichen
# und gibt sich auf der Standardausgabe (stdout) wieder aus
trim() {
  # Liest die Eingabe zeilenweise
  while IFS= read -r line; do
    # Entfernt führende Leerzeichen
    line=${line##*[[:space:]]}
    # Entfernt nachfolgende Leerzeichen
    line=${line%%[[:space:]]*}
    # Gibt die bereinigte Zeile aus, wenn sie nicht leer ist
    echo "$line"
  done
}
 
Danke für die Tips!

Ich habe nicht verstanden, in welchem Zusammenhang Du die Funktion verwendest.
'trim' ist hier ein kleines Script mit dem Inhalt tr '\n' ' ' | sed 's|^ *||g' | sed 's| *$||g' .


Nein sorry, ich habe mich falsch ausgedrückt.
Meinte 'lowercase' weil Build-in Variablen in upper sind.

Finde persönlich Variablen in Uppercase aber besser lesbar. Ich habe niemals in irgendeiner Form programmieren gelernt, so daß alles immer sehr 'zusammengebrettert' ausschaut :-)

if [ -z "$DOIT" ] ; then $PROG ; fi

Habe das durch eval "$PROG" ersetzt, damit Variablen expandiert werden (?).
Der Befehl mkABRges -v > $DESK/TEST wurde vorher nicht ausgeführt.
Ich hoffe, man kann das so machen.

Was im Grunde fehlt:

Daß das gefundene Kommando einfach auf der Konsole ausgegeben wird, und (ohne 'read') einfach per Enter bestätigt werden kann wie ein Text, den ich händisch auf dem Terminal eingebe.

Das würde die Möglichkeit eröffnen, das gefundene Kommando nochmal zu editieren, bevor es ausgeführt wird....
 
trim' ist hier ein kleines Script mit dem Inhalt ...
Ja. Ich hab nur noch eine alternative Implementierung von trim hingestellt. Die ist zwar auch länger, kommt aber ohne externe Programme aus.
Aber beides geht natürlich. :-)

Nein sorry, ich habe mich falsch ausgedrückt.
Meinte 'lowercase' weil Build-in Variablen in upper sind.
Ah ok. Jetzt verstehe ich. :-)
Letztlich ist es egal, wie man Variablen bezeichnet. Wichtig ist halt nur, das man möglichst nicht in irgendwelche Namenskollisionen rein läuft.
Ansonsten gibts natürlich verschiedene Konventionen. Das man zum Beispiel keine Sonderzeichen benutzen sollte und auch nix außerhalb des ASCII-Zeichensatzes, damit einem Zeichensatzprobleme nicht auf die Füße fallen.

Ansonsten ist der Punkt, das Umgebungsvariablen Upper-Case sind natürlich auch valide.

Habe das durch eval "$PROG" ersetzt, damit Variablen expandiert werden (?).
Ja. eval sorgt sozusagen dafür, das übergebene Zeichenketten (in dem Fall der Inhalt der Variable PROG) als Befehl ausgeführt werden.
Im Prinzip kann man Befehle auch wie in der vorherigen Variante ausführen. Das Problem im konkreten Fall ist halt, das Du da ja mit dem Umlenkungszeichen auch mehr machst. Aber durch geschicktes einsetzen von eval hast Du das Problem ja umschifft. :-)

Daß das gefundene Kommando einfach auf der Konsole ausgegeben wird, und (ohne 'read') einfach per Enter bestätigt werden kann wie ein Text, den ich händisch auf dem Terminal eingebe.
Das ist eine gute Fragestellung auf die ich gerade spontan keine Antwort habe. Bin aber auch nicht so vertraut mit der Korn-Shell.
Vielleicht fällt mir dazu noch was ein.
Gibt ja grundsätzlich zwei Möglichkeiten. Man ruft 'ne "interactive-editline" auf (womit man aber wieder ein externes Programm braucht) oder man fügt das am Prompt ein (was natürlich am besten wäre).
Ansonsten könntest Du das ja mit xsel machen (so ähnlich wie in Posting #3) und somit dann in die Shell einfügen. Ist keine schöne Lösung, aber so machst Du es editierbar.
 
Zuletzt bearbeitet:
Ansonsten könntest Du das ja mit xsel machen (so ähnlich wie in Posting #3) und somit dann in die Shell einfügen.

Du hast recht, das geht, aber man muss zur Maus greifen und die mittlere Taste bemühen.
Vermutlich ginge das mit 'xdotools' oder ähnlichem.

Es gibt auch noch etwas anderes, was in dem Script fehlt:

Code:
        if [ "$DOIT" = '' ] ; then

            echo $PROG >> $HIST
            eval "$PROG"
        fi

Ich habe es jetzt so (echo $PROG >> $HIST) , damit der ausgeführte Befehl in der History direkt wieder aufrufbar ist. Das greift aber nur in einer neuen Konsole.

Eigentlich müsste die History direkt neu eingelesen werden...
 
Zurück
Oben