Merkwürdiges Verhalten des Bash-Verlaufs beim Ausführen mehrerer Sitzungen

15

Wie wird der Befehlszeilenverlauf gespeichert, wenn ich mehrere Terminalfenster verwende? Ich weiß, dass es in gespeichert ist, .bash_historyaber ich kann die Logik für die Verwendung des Verlaufs nicht sehen, wenn ich ein neues Fenster öffne. Es fühlt sich fast nicht deterministisch an in dem Sinne, dass ich nie weiß, welchen Befehl ich sehen werde, wenn ich versuche, den Pfeil nach oben in einem neuen Fenster zu verwenden.

Kann das jemand erklären?

Gibt es eine Möglichkeit, den Verlauf so zu steuern, dass ich den Verlauf eines bestimmten Fensters wiederverwenden kann?

Alex Gitelman
quelle

Antworten:

14

Um das Verhalten des Bash-Verlaufs zu verstehen, müssen Sie zunächst Folgendes wissen:

  1. In der Verlaufsdatei befindet sich der Verlauf.
  2. Es gibt die Geschichte in der Erinnerung an einen Bash-Prozess.
  3. Der Verlauf im Speicher eines Bash-Prozesses wird nicht mit dem Verlauf im Speicher eines anderen Bash-Prozesses synchronisiert.
  4. Der Verlauf im Speicher eines Bash-Prozesses wird nicht mit dem Verlauf in der Datei synchronisiert, es sei denn, Sie werden ausdrücklich zu oder während eines bestimmten Ereignisses aufgefordert (siehe unten).

Unter Verwendung der Standardeinstellungen sieht der Lebenszyklus einer Bash-Sitzung in Bezug auf den Verlauf wie folgt aus:

  1. Während des Startvorgangs liest bash die Verlaufsdatei. Der Inhalt der Verlaufsdatei befindet sich jetzt im Speicher des Bash-Prozesses.
  2. Während des normalen Gebrauchs wird nur der Verlauf im Speicher manipuliert.
  3. Während des Herunterfahrens wird der Verlauf im Speicher in die Verlaufsdatei geschrieben, wobei der vorherige Inhalt der Verlaufsdatei überschrieben wird.

Das scheinbar nicht deterministische Verhalten, das Sie beobachtet haben, liegt hauptsächlich daran, dass der Inhalt der Verlaufsdatei immer der Verlauf der letzten geschlossenen Bash-Sitzung ist und Bash die Verlaufsdatei nur beim Start liest.

Lesen Sie das Bash-Handbuch, um eine detailliertere Beschreibung des Startvorgangs und des Herunterfahrens zu erhalten.

Beachten Sie, dass ich mit Standardeinstellungen die Standardeinstellungen von Bash meine. Ihre Distribution hat möglicherweise ein .bashrc(oder /etc/bash.bashrc) bereitgestellt, das dieses Verhalten ändert.

Durch Aktivieren der Shell-Option histappendkönnen Sie festlegen, dass bash die Verlaufsdatei anfügt, anstatt sie zu überschreiben. Sie können histappendmit dem Befehl aktivieren shopt -s histappend. Damit diese Option immer aktiviert ist, müssen Sie den Befehl in Ihre .bashrc(oder eine andere Initialisierungsdatei) einfügen. Weitere Informationen zum shoptBefehl finden Sie im Bash-Handbuch

Beachten Sie, dass durch die Aktivierung histappenddas scheinbar nicht deterministische Verhalten nicht wesentlich verringert wird. Dies liegt daran, dass für jede Bash-Sitzung immer noch eine eigene Historie gespeichert ist. Es ist möglich, einen meist synchronisierten Bash-Verlauf zu haben. Es gibt eine Anleitung, wie jeder Bash-Prozess einen weitgehend synchronisierten Verlauf in einem Thread beim Stapelüberlauf erhält .

Mit dem eingebauten Befehl historykönnen Sie bash explizit anweisen , den Verlauf von einer Datei in den Speicher zu lesen oder vom Speicher in die Datei zu schreiben. Beispiel: history -rLiest den Inhalt der Datei und hängt ihn an den Verlauf im Speicher an. history -wschreibt den aktuellen Verlauf vom Speicher in die Datei und überschreibt den vorherigen Inhalt. Dies ist im Grunde, was beim Herunterfahren passiert. Weitere Informationen zum historyBefehl finden Sie im Bash-Handbuch

Der Vollständigkeit halber finden Sie hier eine Liste der internen Variablen, die das Verlaufsverhalten ändern:

  • HISTFILE: Die Datei, aus der gelesen und in die der Verlauf geschrieben werden soll.
  • HISTFILESIZE: die maximale Zeilenanzahl für die Verlaufsdatei.
  • HISTSIZE: Die maximale Zeilenanzahl für den Verlauf im Speicher.
  • HISTCONTROL, HISTIGNORE, HISTTIMEFORMAT: Nicht für diese Diskussion relevant. Lesen Sie das Bash-Handbuch für Details.
lesmana
quelle
Gute Erklärung. Sie haben das Herunterfahren erwähnt, aber was ist mit dem Beenden der Terminalsitzung? Die Sitzung kann durch Abmelden oder über die Benutzeroberfläche oder auf andere Weise, z. B. durch Unterbrechen der Netzwerkverbindung, beendet werden. Wenn die gesamte Verlaufsdatei ersetzt wird und Sie mehrere Sitzungen haben, wird der Verlauf der zuletzt geschlossenen Sitzung in der Verlaufsdatei verwendet? Das könnte nicht deterministisches Verhalten erklären.
Alex Gitelman
Lebenszykluspunkt (3) ist nicht korrekt. Es scheint, als würde nur die erste Bash-Sitzung jemals in die Verlaufsdatei schreiben. Test: Öffnen Sie 2 Sitzungen in der Reihenfolge a, b. Mach 'hallo' in b . Dann Ausfahrt in b . Dann öffnen Sie eine neue Sitzung c . Diese Sitzung hat kein Echo Hallo in der Geschichte.
user606723
@AlexGitelman: Wenn ein Bash-Prozess beendet wird, hat er keine Chance, die Verlaufsdatei zu überschreiben. und ja, der Verlauf der letzten geschlossenen Sitzung ist derjenige, der in der Verlaufsdatei enthalten sein wird.
Lesmana
@ user606723: Punkt 3 ist korrekt. Lies das Bash-Handbuch. Experimentieren Sie erneut mit einer minimalen .bashrcDatei. Beachten Sie, dass Ihre Distribution möglicherweise einige Einstellungen in geändert hat /etc/bash.bashrc. überprüfen Sie speziell für die Shell-Option histappend.
Lesmana
2

http://www.gnu.org/software/bash/manual/bashref.html#Using-History-Interactively

Möglicherweise können Sie mit einem der Terminals die Schreibweise der Verlaufsdatei ändern, dh "history -a" oder "history -w" in dem Terminal ausführen, in dem Sie den Verlauf speichern möchten, und dann "history -r" in die anderen Terminals. Kommt darauf an, was du machen willst.

cjc
quelle
0

AFAIK, die Bash-Befehle werden nach Beendigung der SSH-Sitzung gespeichert. Daher werden die Befehle nicht gespeichert, wenn eine Sitzung abnormal beendet wird (z. B. aufgrund eines Netzwerkfehlers). Ich spreche hier von SSH-Sitzungen. Die lokalen Terminals können einen ähnlichen Ansatz verwenden.

Wenn Sie mehrere Sitzungen gleichzeitig öffnen, werden die in einer Sitzung eingegebenen Befehle in der anderen Sitzung nicht angezeigt, solange beide aktiv sind. Diese Befehle werden jedoch angezeigt, wenn Sie die Sitzung beenden und erneut öffnen.

Khaled
quelle
Dies ist nicht das Verhalten, das ich erlebt habe. Ich kann dies bestätigen, indem ich einen kurzen Test durchführe, in dem ich eine SSH-Sitzung öffne, einen Befehl ausführe und ein ordnungsgemäßes Beenden vornehme. In diesem Fall hatte ich eine andere zuvor aktive SSH-Sitzung. In dieser bereits vorhandenen Bash-Sitzung überprüfe ich .bash_history und finde nichts aufgezeichnet. Ich halte es für wahrscheinlich, dass die erste Bash-Sitzung die einzige ist, die in .bash_history aufzeichnet.
user606723
Das Beenden Ihrer Sitzung wirkt sich nicht auf die aktuell ausgeführten Sitzungen aus, wirkt sich jedoch auf die neuen Sitzungen aus!
Khaled
Was ist, wenn ich nicht SSH, sondern das Gnome-Terminalfenster über die Benutzeroberfläche schließe?
Alex Gitelman
Es muss überprüft werden. Derzeit habe ich keinen Zugang zu einem Gnome-Terminal!
Khaled
@Khaled, Getestet, wirkt sich nicht auf neue Sitzungen aus. (Ich habe ohnehin .bash_history überprüft, wo bash den Befehlsverlauf für neue Sitzungen abruft. Ich wusste also, dass dies nicht funktionieren würde, aber ich habe Sie trotzdem belustigt.)
user606723