Erstens ist dies kein Duplikat eines vorhandenen Threads auf SE. Ich habe diese beiden Threads ( 1. , 2. ) über eine bessere Bash-Geschichte gelesen , aber keine der Antworten funktioniert - - ich bin übrigens auf Fedora 15.
Ich habe der .bashrc
Datei im Benutzerverzeichnis (/ home / aahan /) Folgendes hinzugefügt , 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 der Bash-Geschichte will (Priorität):
- Speichern Sie keine Duplikate, löschen Sie vorhandene
- Teilen Sie die Historie sofort mit allen offenen Terminals
- Verlauf immer anhängen, nicht überschreiben
- Speichern von mehrzeiligen Befehlen als einzelner Befehl (standardmäßig deaktiviert)
- Was ist die Standardgröße für Verlauf und Verlaufsdatei?
bash
command-history
da ich bin
quelle
quelle
echo $SHELL
). Funktionieren die Einstellungen, wenn Sie sie manuell von Ihrer offenen Shell aus ausführen? Da sie für so viele andere funktionieren, sind die Einstellungen offensichtlich richtig, und Sie implementieren sie nur falsch. Und kein Fedora15 / Gnome3 / als virtuelle Maschine hat wenig mit der eigentlichen Funktion von zu tunbash
..bashrc
Datei eingefügt . Ist das falsch? Können Sie diesem Beitrag eine "Antwort" mit den tatsächlichen Shell-Befehlen hinzufügen? (bitte mit meinem noob-.bashrc
ARE-Shell-Befehlen schreiben . Skripte sind nur eine Reihe von Shell-Befehlen. Auch die Bearbeitung, die Sie kürzlich vorgenommen haben, um dasexport
Bit zu entfernen, war eine schlechte Idee, die beibehalten werden sollte.Antworten:
Dies ist tatsächlich ein wirklich interessantes Verhalten und ich gebe zu, 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 auf das Terminal drücken müssen, um die Historie auf ein anderes (aktualisiertes) Terminal "übertragen" zu lassen. EnterDort möchten Sie die Historie abrufen.
Option 1:
Dies hat zwei Nachteile:
Option 2:
(Ja, keine Notwendigkeit
shopt -s histappend
und ja, es musshistory -c
in der Mitte seinPROMPT_COMMAND
) Diese Version hat auch zwei wichtige Nachteile:history
Befehl kann eine falsche Ausgabe liefern - siehe unten.[Bearbeiten] "Und der Gewinner ist ..."
Option 3:
Das ist so weit wie es geht. Es ist die einzige Option, bei der beide
erasedups
und die gemeinsame Historie gleichzeitig arbeiten. Dies ist wahrscheinlich die endgültige Lösung für alle Ihre Probleme, Aahan.2. Warum scheint Option 2 nicht zu funktionieren (oder: was funktioniert wirklich nicht wie erwartet)?
Wie bereits erwähnt, funktioniert jede der oben genannten Lösungen anders. Aber die irreführende Interpretation, wie die Einstellungen arbeiten kommt von der Ausgabe des Analyse -
history
Befehls . In vielen Fällen kann der Befehl eine falsche Ausgabe liefern . Warum? Weil es vor der Folge andererhistory
Befehle ausgeführt wird, die in derPROMPT_COMMAND
! Wenn Sie jedoch die zweite oder dritte Option verwenden, können Sie die Änderungen des.bash_history
Inhalts überwachen (watch -n1 "tail -n20 .bash_history"
z. B. mithilfe von) und den tatsächlichen Verlauf abrufen.3. Warum ist Option 3 so kompliziert?
Es liegt alles in der Art und Weise, wie es
erasedups
funktioniert. Da die bash Handbuch erklärt, „(...)erasedups
bewirkt , dass alle vorherigen Zeilen die aktuelle Zeile passend aus der History - Liste entfernt werden , bevor diese Zeile gespeichert wird“ . Das ist also wirklich das, was das OP wollte (und nicht nur, wie ich vorher dachte, dass keine Duplikate nacheinander auftauchen ) . Hier ist der Grund, warum jeder derhistory -.
Befehle entweder in der folgenden Liste stehen muss oder nicht darfPROMPT_COMMAND
:history -n
muss vorher da seinhistory -w
, um von.bash_history
den Befehlen zu lesen, die von einem anderen Terminal gespeichert wurden,history -w
muss da sein, um den Verlauf zu speichern, um Duplikate abzulegen und zu löschen,history -a
darf nicht statt dort platziert werdenhistory -w
, da es nicht zum Löschen von Duplikaten führt,history -c
wird auch benötigt , um zu verhindern, dass der Verlaufspuffer nach jedem Befehl gelöscht wird.und schließlich
history -r
wird benötigt , um den Verlaufspuffer aus einer Datei wiederherzustellen und damit den Verlauf für alle Terminalsitzungen gemeinsam zu nutzen.quelle
watch "tail -n 20 .bash_history"
statt der auch die verwendentail -f .bash_history
.history -c
wird auch benötigt, weil dadurch verhindert wird, dass der Verlaufspuffer nach jedem Befehl in den Papierkorb verschoben wird. Warum tritt dieser Papierkorb auf?In Ihrem Eingabeaufforderungsbefehl verwenden Sie den
-c
Schalter. Vonman bash
:Um Ihren Verlauf mit allen offenen Terminals zu teilen, können Sie Folgendes verwenden
-n
:Die Standardgröße finden Sie auch im Handbuch:
So speichern Sie mehrzeilige Befehle:
Außerdem sollten Sie HIST * -Befehlen keine Präfixe voranstellen
export
- es handelt sich um reine Bash-Variablen, nicht um Umgebungsvariablen. DiesHISTCONTROL=ignoredups:erasedups
ist ausreichend.quelle
export PROMPT_COMMAND="history -a; history -n; history -r; $PROMPT_COMMAND"
ist also richtig? Wissen Sie auch, wie ich die Verlaufsdatei dazu bringen kann, mehrzeilige Befehle als einen einzigen Befehl zu speichern (was standardmäßig deaktiviert ist)?shopt -s cmdhist
werden mehrere Zeilen gespeichert.HISTCONTROL=ignoredups:erasedups
es nicht funktionieren. Ich habe auch versucht, genau das in der.bashrc
Datei zu haben (unter den benutzerdefinierten Funktionen). Irgendeine Idee, was falsch sein könnte? Ich verwende Fedora 15 auf einer virtuellen Maschine - - Windows 7-Host./etc/bashrc
,.bash_profile
das diese überschreibt..bash_profile
Datei. Was den Inhalt in/etc/bashrc
ich es hier setzen, nehmen Sie bitte einen Blick - pastebin.com/Uae6sE6sDies ist, was ich mir ausgedacht habe und ich bin soweit zufrieden damit ...
ANMERKUNGEN:
HISTIGNORE
ignoriert alle Befehle, die keine Argumente haben. Dies kann von einigen Leuten nicht wünschenswert sein und kann weggelassen werden.quelle
Verwenden Sie dies stattdessen:
quelle
Es funktioniert nicht, weil Sie vergessen:
Aber es scheint
history -n
nur fehlerhaft zu sein, wennexport HISTCONTROL=ignoreboth:erasedups
es in Kraft ist.Lass uns experimentieren:
Hier schalten wir das Löschen von Dups ein, schalten den Verlauf auf eine benutzerdefinierte Datei um und löschen den Verlauf. Nachdem alle Befehle ausgeführt wurden, haben wir eine leere Verlaufsdatei und einen Befehl im aktuellen Verlauf.
Öffnen Sie das zweite Terminal und führen Sie auch diese sechs Befehle aus. Nachdem:
Jetzt hat Ihr aktueller Verlauf zwei Befehle und die Verlaufsdatei hat:
Zurück zum ersten Terminal:
Huh ... keiner der
echo
Befehle wird gelesen. Wechseln Sie erneut zum zweiten Terminal und:Die Verlaufsdatei lautet nun:
Wechseln Sie wieder zum ersten Terminal:
Sie können sehen, dass der
echo "Z"
Befehl mit zusammengeführt wirdhistory -n
.Ein weiterer Fehler ist, dass Befehle aus dem Verlauf nach Befehlsnummer und nicht nach Befehlszeit gelesen werden, denke ich. Ich erwarte, dass andere
echo
Befehle in der Historie auftauchtenquelle
erasedups schneidet die führenden und nachfolgenden Leerzeichen nicht ab (wie in einigen Sprachen chomp). Das ist ein Fehler. Durch das Löschen werden auch nicht alle vorherigen Einträge gelöscht.
quelle