Wie man Zsh dazu bringt, fehlgeschlagene Befehle nicht zu speichern

13

Problem

Ich verwende oh-my-zsh und Antigen, um mein Zsh zu verwalten.

Manchmal gebe ich versehentlich einen falschen / fehlgeschlagenen Befehl in Zsh ein und es ist sehr ärgerlich, wenn das Plugin zsh-autosuggestions diese Befehle auslöst .

Sagen wir zum Beispiel, ich habe gut statuseher getippt als git status.

Wenn ich nun versuche, den richtigen Befehl erneut einzugeben g, wird nach der Eingabe das Autosuggestion-Plugin angezeigt, gut statusda dies die engste Übereinstimmung in der jüngeren Geschichte darstellt. Aber das ist ein fehlgeschlagener Befehl!

Was ich tun möchte, ist zu verhindern, dass diese fehlgeschlagenen Befehle meinen Verlauf "verschmutzen", damit das Autosuggestion-Plugin sie nicht vorschlägt.

Was habe ich getan

Ich habe danach gesucht und die beste Übereinstimmung, um Einträge aus dem Verlauf herauszuhalten, ist das Festlegen von HIST_IGNORE_SPACE oder Methoden zum Ignorieren bestimmter Befehle oder zum manuellen Löschen von Befehlen nach deren Eingabe. Sehen Sie dies und das . Aber wie @Adaephon 52 feststellte, geschieht dies, nachdem die Tat getan ist.

Was ich überlege zu tun

Ich habe gerade vor, eine Funktion zu schreiben, die jedes Mal ausgelöst wird, wenn ein fehlgeschlagener Befehl in Zsh eingegeben wird, um den neuesten Eintrag aus dem Verlauf zu löschen. Ich bin jedoch nicht vertraut genug mit Zsh, um zu wissen, ob diese Art von Trigger existiert oder wie man das macht.


Hinweis zur akzeptierten Lösung

Für diejenigen, die an diesem Problem interessiert sind, funktioniert die akzeptierte Lösung in dem Sinne, dass fehlgeschlagene Befehle nicht in der Verlaufsdatei gespeichert werden. fc -loder historybestätigt dies.

Es scheint jedoch, dass das zsh-autosuggestions-Plugin eine Art lokales Caching durchführt (oder Vorschläge mithilfe eines anderen Mechanismus generiert), sodass die fehlgeschlagenen Befehle weiterhin vorgeschlagen werden, jedoch nur, wenn die Sitzung nicht beendet ist . Wenn der Benutzer eine neue Instanz der Shell startet und das Plugin vermutlich den zwischengespeicherten Verlauf laden muss, werden die fehlgeschlagenen Befehle nicht mehr vorgeschlagen (es sei denn, Sie geben sie natürlich erneut ein).

Die vorgeschlagene Lösung ist technisch korrekt, da ich meine Frage (fälschlicherweise) so formuliert habe, dass nur eine Antwort erforderlich ist, die Zsh daran hindert, die fehlgeschlagenen Befehle zu speichern, und die akzeptierte Lösung dies tut (wenn auch in begrenztem Umfang; siehe Link in Lösung für Einzelheiten).

Jeder, der mit Shell -Skripten vertraut ist (ich bin es nicht) und motiviert genug ist, kann das Skript zsh-autosuggestions überprüfen .

Lichtchemiker
quelle

Antworten:

12

Bart Schaefer schlug den folgenden Ansatz für dieselbe Frage auf derMailinglisteder zsh-Benutzer vor :

 zshaddhistory() { whence ${${(z)1}[1]} >| /dev/null || return 1 }

Diese Funktion wird ausgeführt, bevor die Befehlszeile in den Verlauf geschrieben wird. Wenn 1 zurückgegeben wird, wird die aktuelle Befehlszeile weder an die Verlaufsdatei noch an den lokalen Verlaufsstapel angehängt. Die Überprüfung, ob der Befehl einen Fehler auslöst, der nicht gefunden wurde , deckt jedoch nur einfache Fälle ab. ZB wird diese Zeile in der Geschichte stehen:

echo foo; echooo bar

Aber es funktioniert gut für Ihr Beispiel

gut status

Bitte beachten Sie, dass der falsche Befehl angezeigt wird UP-ARROW(damit Sie ihn korrigieren können!), Aber nicht im Verlaufsstapel enthalten ist. erkundigen Sie sich bei fc -l.

mpy
quelle
Dadurch wird das Caching fehlgeschlagener Befehle gestoppt. Es scheint jedoch, dass das Plugin für zsh-autosuggestions ein eigenes lokales Caching der letzten Einträge durchführt, sodass diese Vorschläge weiterhin angezeigt werden, solange die Sitzung noch nicht beendet ist. Sobald ich eine neue Shell öffne und vermutlich den zwischengespeicherten Verlauf laden muss, werden sie nicht mehr vorgeschlagen. Dies löste einen Teil des Problems und ich denke, ich muss mich beim Betreuer des zsh-autosuggestions-Plugins erkundigen, um das verbleibende Problem zu beheben. Trotzdem danke!
Lichtchemiker
Wo setzen Sie diese Funktion?
Daniel
1
@ Daniel: In jeder Konfigurationsdatei liest zsh beim Start, normalerweise Ihre ~/.zshrc.
Mpy
Ich habe es mit einem Alias ​​anstelle eines Befehls (Z-Shell) versucht. Ein fehlgeschlagener Alias ​​taucht immer noch in der Zsh-Geschichte auf. @mpy
Tuyen Pham
0

Der integrierte fcBefehl unterstützt das Bearbeiten Ihres Verlaufs. Falls Sie zB den vorherigen Befehl falsch eingegeben haben, können Sie Folgendes eingeben:

$ fc -e nano -1

Sie können durch nanoden Befehl Ihres bevorzugten Editors ersetzen . Sie können die EDITORVariable (Parameter) auch in Ihrer zsh-Konfiguration festlegen . ( Siehe verweisende SO-Seite )

Sie müssen die Datei speichern (die von fc in einem temporären Systemordner erstellt wurde). Danach werden die Zeilen bearbeitet. Enterwird ausgeführt oder Sie können drücken Ctrl+C, um die Bearbeitung abzuschließen.

Weitere Details finden Sie in der zsh-Dokumentation: Zsh: Bearbeitungsverlauf


Falls Sie den gesamten Verlauf bearbeiten möchten

$ fc -W; nano "$HISTFILE"; fc -R

... ersetzen Sie wieder Nano, wenn Sie möchten

Es schreibt einfach den Verlauf einschließlich des Caches aus und öffnet die Datei mit einem Editor.

Bitte beachten Sie, dass zsh drei Arten von Geschichte kennt:

  • Intern : Befehle, die Sie seit der Anmeldung eingegeben haben
  • Lokal : die in der aktiven Shell verfügbare - [HISTFILE + Internal]
  • "Global" : Es hängt davon ab, aber sagen wir, es ist die in HISTFILE festgelegte Datei

Beachten Sie bitte, dass SHARE_HISTORYSie den fc -WBefehl zuerst in diesen Shells ausführen sollten , wenn Ihre Verlaufsdatei freigegeben ist ( ) und Sie mehr als eine zsh-Shell mit dem betreffenden Benutzer geöffnet haben . Wenn Sie mit der Bearbeitung fertig sind, führen Sie sie aus fc -R. Andernfalls werden die in diesen Shells eingegebenen Befehle nicht gespeichert und erkennen dann Ihre manuelle Bearbeitung der HISTFILE.

Geck0
quelle
2
Die Frage besagt, dass das OP Methoden gefunden hat, um Befehle manuell einzugeben, nachdem sie eingegeben wurden. Sie fragt nach einer Möglichkeit, dies automatisch zu tun, wenn ein Befehl mit dem Befehl "nicht gefunden" oder einem anderen Fehler fehlschlägt.
Scott
-2

Ich bin mir nicht sicher, wie omz es ausführt, aber sowohl in Bash- als auch in regulären Zsh-Präfixen mit einem Leerzeichen wird es aus der .history und fortan auch aus der automatischen Vervollständigung / Suggestion herausgehalten

dh

<space>ll -ahZ  /home/%USER
linuxdev2013
quelle
3
Das OP möchte falsche / fehlgeschlagene Befehle aus dem Verlauf behalten. Und da er nur weiß, dass der Befehl nach dem Ausführen falsch war , löst das Hinzufügen eines Leerzeichens vor dem Ausführen das Problem nicht.
Adaephon
@ Adaephon Genau. Ich weiß, dass es möglich ist, dass ZSH Befehle ignoriert, die mit Leerzeichen beginnen. Vielleicht hätte ich das in meinem Beitrag erwähnen sollen.
Lichtchemiker
persönlich behalte ich keine Historie (indem ich das mache) eine andere Lösung - steige aus dem beschissen gepflegten Oh-my-zsh für reines zsh oder Prestzo (besser gepflegt und vernünftigere aktuelle Konfigurationen ... dieser Mangel an Funktionalität ist seit einiger Zeit in den "Problemen"
linuxdev2013