GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Bash-Verlauf:„Ignoredups“- und „Erasedups“-Einstellungskonflikt mit gemeinsamem Verlauf über Sitzungen hinweg?

Zunächst einmal ist dies kein Duplikat bestehender Threads auf SE. Ich habe diese beiden Threads (1., 2.) zur besseren Bash-Geschichte gelesen, aber keine der Antworten funktioniert – – Ich bin übrigens auf Fedora 15.

Ich habe Folgendes zur .bashrc hinzugefügt Datei im Benutzerverzeichnis (/home/aahan/), und es funktioniert nicht. Hat jemand eine Ahnung?

HISTCONTROL=ignoredups:erasedups  # no duplicate entries
HISTSIZE=1000                     # custom history size
HISTFILESIZE=100000                 # custom history file size
shopt -s histappend                      # append to history, don't overwrite it
PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"  # Save and reload the history after each command finishes

Okay, das ist, was ich mit dem Bash-Verlauf (Priorität) will:

  • keine Duplikate speichern, vorhandene löschen
  • Verlauf sofort mit allen offenen Terminals teilen
  • Verlauf immer anhängen, nicht überschreiben
  • mehrzeilige Befehle als einzelnen Befehl speichern (standardmäßig deaktiviert)
  • Was ist die Standardgröße des Verlaufs und der Verlaufsdatei?

Akzeptierte Antwort:

Das ist eigentlich ein wirklich interessantes Verhalten und ich gestehe, dass ich die Frage am Anfang stark unterschätzt habe. Aber zuerst die Fakten:

1. Was funktioniert

Die Funktionalität kann auf verschiedene Arten erreicht werden, obwohl jede etwas anders funktioniert. Beachten Sie, dass Sie in jedem Fall, um die Historie auf ein anderes Terminal „übertragen“ (aktualisieren) zu lassen, Enter drücken müssen im Terminal, wo er/sie den Verlauf abrufen möchte.

  • Möglichkeit 1:

     shopt -s histappend
     HISTCONTROL=ignoredups
     PROMPT_COMMAND="history -a; history -n; $PROMPT_COMMAND"
    

Dies hat zwei Nachteile:

  1. Bei der Anmeldung (Öffnen eines Terminals) wird der letzte Befehl aus der Verlaufsdatei zweimal in den Verlaufspuffer des aktuellen Terminals eingelesen;
  2. Die Puffer verschiedener Terminals bleiben nicht synchron mit der Verlaufsdatei.
  • Möglichkeit 2:

     HISTCONTROL=ignoredups
     PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
    

(Ja, shopt -s histappend ist nicht erforderlich und ja, es muss sein history -c in der Mitte von PROMPT_COMMAND )
Diese Version hat auch zwei wichtige Nachteile:

  1. Die History-Datei muss initialisiert werden. Es muss mindestens eine nicht leere Zeile enthalten (kann alles sein).
  2. Die history Befehl kann eine falsche Ausgabe liefern – siehe unten.

[Bearbeiten] „Und der Gewinner ist…“

  • Möglichkeit 3:

     HISTCONTROL=ignoredups:erasedups
     shopt -s histappend
     PROMPT_COMMAND="history -n; history -w; history -c; history -r; $PROMPT_COMMAND"
    

Dies ist so weit wie es geht. Es ist das einzige Option, beide erasedups zu haben und gemeinsame Geschichte gleichzeitig arbeiten. Das ist wahrscheinlich die endgültige Lösung zu all deinen Problemen, Aahan.

2. Warum funktioniert Option 2 scheint nicht zu funktionieren (oder:was wirklich funktioniert nicht wie erwartet)?

Wie ich bereits erwähnt habe, funktioniert jede der oben genannten Lösungen anders. Aber die irreführendste Interpretation der Funktionsweise der Einstellungen ergibt sich aus der Analyse der Ausgabe von history Befehl . In vielen Fällen kann der Befehl false ergeben Ausgang. Wieso den? Weil es vorher ausgeführt wird die Folge der anderen history Befehle, die in PROMPT_COMMAND enthalten sind ! Wenn Sie jedoch die zweite oder dritte Option verwenden, können Sie die Änderungen von .bash_history überwachen Inhalte (mit watch -n1 "tail -n20 .bash_history" zum Beispiel) und sehen Sie, was die wahre Geschichte ist.

Verwandte:Warum ändert sich die Ausgangsspannung eines Signalgenerators mit seiner Frequenzeinstellung?

3. Warum Option 3 ist so kompliziert?

Es liegt alles an der Art erasedups funktioniert. Wie es im Bash-Handbuch heißt, “(…) erasedups bewirkt, dass alle vorherigen Zeilen, die mit der aktuellen Zeile übereinstimmen, aus der Verlaufsliste entfernt werden, bevor diese Zeile gespeichert wird” . Das ist also wirklich das, was das OP wollte (und nicht nur, wie ich zuvor dachte, dass keine Duplikate nacheinander erscheinen ) . Hier ist, warum jeder der history -. Befehle müssen oder können nicht im PROMPT_COMMAND stehen :

  • history -n hat vor history -w vorhanden sein aus .bash_history zu lesen die von jedem anderen Terminal gespeicherten Befehle,

  • history -w hat dort sein, um den neuen Verlauf in der Datei zu speichern, nachdem bash geprüft hat, ob der Befehl ein Duplikat war,

  • history -a darf nicht dort anstelle von history -w platziert werden , da es jeden neuen Befehl zur Datei hinzufügt, unabhängig davon, ob er als Duplikat geprüft wurde.

  • history -c wird auch benötigt weil es verhindert, dass der Verlaufspuffer nach jedem Befehl gelöscht wird,

  • und schließlich history -r wird benötigt um den Verlaufspuffer aus der Datei wiederherzustellen, wodurch der Verlauf endlich über Terminalsitzungen hinweg geteilt wird.

Beachten Sie, dass diese Lösung die Verlaufsreihenfolge durcheinander bringt, indem der gesamte Verlauf von anderen Terminals vor den neuesten Befehl gestellt wird, der im aktuellen Terminal eingegeben wurde. Es löscht auch keine doppelten Zeilen, die sich bereits in der Verlaufsdatei befinden, es sei denn, Sie geben diesen Befehl erneut ein.


Linux
  1. Verwenden von Wortmodifikatoren mit Bash-Verlauf in Linux

  2. So erfassen Sie Terminalsitzungen und geben sie mit dem Linux-Skriptbefehl aus

  3. Bash-Datei Massenumbenennung mit Zähler?

  4. Suchen Sie eine Datei mit den Befehlen Suchen und Suchen in Linux

  5. Hinzufügen eines Zeitstempels zu einem Dateinamen mit mv in BASH

Verbessern Sie Ihren Shell-Verlauf mit Loki und fzf

Linux Zip- und Unzip-Befehl mit Beispielen

So sichern und wiederherstellen Sie den Verlauf des Linux-Terminals

Bash-Umleitung mit Beispielen erklärt

So löschen Sie den Bash-Verlauf in Linux und Mac

Entfernt eine bestimmte Zeile aus der Bash-Verlaufsdatei