Warum wird die Befehlsgeschichte nur beim Beenden gespeichert?

476
Fidel

Ich versuche, pro Tab / Terminal eine andere Verlaufsdatei zu speichern, kann es jedoch nicht sofort nach dem Ausführen eines Befehls speichern. Die Historie wird nur gespeichert, wenn ich "exit" starte.

Dies ist ein Problem, denn ich möchte eine Kopie der Historie haben, falls das Terminal oder der Computer abstürzt.

Nachdem ich mich im Internet umgesehen habe, habe ich Folgendes in meiner .bashrc-Datei:

export HISTFILE="$HOME/HISTORIES/bash_history_$(basename $(tty))_$(date '+%Y-%m-%d_%H-%M-%S_%Z')" export HISTCONTROL=ignoreboth export HISTFILESIZE=10000 export HISTSIZE=10000 shopt -s histappend PROMPT_COMMAND=$(history -a; $PROMPT_COMMAND) 

Irgendeine Idee, was ich falsch mache?

Vielen Dank.

0
Existiert das Verzeichnis "$ HOME / HISTORIES"? Wenn nicht, erstellen Sie es. mt025 vor 5 Jahren 0
Natürlich existiert es ... Fidel vor 5 Jahren 0

3 Antworten auf die Frage

3
William Pursell

Sie weisen PROMPT_COMMAND falsch zu. Wenn du schreibst

PROMPT_COMMAND=$(history -a; $PROMPT_COMMAND) 

Sie führen 'history -a' aus (was keine Ausgabe erzeugt) und dann $ PROMPT_COMMAND (das während der Startskripts möglicherweise leer ist) und weisen die Ausgabe dieser beiden Befehle (die leere Zeichenfolge) PROMPT_COMMAND zu. Was Sie wollen, ist nur:

PROMPT_COMMAND='history -a' 

Wenn Sie es an einen aktuell vorhandenen Befehl anhängen möchten, tun Sie

PROMPT_COMMAND+="history -a$$PROMPT_COMMAND" 
Danke, aber immer noch nicht funktioniert. Ich habe beide Dinge ausprobiert. Die Datei wird nur beim Ausführen von exit gespeichert. Fidel vor 5 Jahren 0
Was ist der aktuelle Wert von PROMPT_COMMAND? Wenn es sich um "history -a" handelt, was passiert, wenn Sie $ HISTFILE "reißen"? Beachten Sie, dass PROMPT_COMMAND erst ausgeführt wird, wenn Ihr Befehl beendet ist. Daher können Sie `history -a` lieber in einen Debug-Trap setzen, der vor einem Befehl ausgeführt wird. William Pursell vor 5 Jahren 0
Der Wert von PROMPT_COMMAND ist history -a. Die $ HISTFILE existiert nicht (wie ich von Anfang an gesagt habe, sie wird nur erstellt, wenn exit ausgeführt wird), daher gibt das Ende dieser Variablen einen Fehler "kann nicht öffnen" zurück. Kannst du die "Debug-Falle" besser erklären? Fidel vor 5 Jahren 0
Versuchen Sie `PROMPT_COMMAND = ', und berühren Sie $ HISTFILE; history -a'` Oder `trap 'touch $ HISTFILE; Geschichte -a "DEBUG" William Pursell vor 5 Jahren 0
Gleich. Bei beiden ist das Ergebnis das gleiche. Der einzige Unterschied besteht darin, dass jetzt die $ HISTFILE vorhanden ist, wenn ich ein neues Terminal starte. Es wird jedoch nichts geschrieben, bis ich den Vorgang beendet habe. Fidel vor 5 Jahren 0
Also vermute ich, dass das unmöglich ist? Fidel vor 5 Jahren 0
Es ist überhaupt nicht unmöglich. Ich zerlegte meine Historie in separate Dateien, die auf der PID der Shell basieren, wobei "history -a" in einer Debug-Falle verwendet wurde, und füge sie dann in einer gemeinsamen Datei mit Statusinformationen, aktuellem Arbeitsverzeichnis und anderen Metadaten in einem PROMPT_COMMAND zusammen . Sie müssen mehr Debugging durchführen. Haben Sie versucht, während des PROMPT_COMMAND Diagnoseinformationen zu drucken? William Pursell vor 5 Jahren 0
Welche Version von Bash laufen Sie? William Pursell vor 5 Jahren 0
Danke, aber ich weiß nicht, ob ich mehr Debugging machen kann. Die Basisversion ist: 4.2.1 (2) (x86_64-redhat-linux-gnu) Fidel vor 5 Jahren 0
1
Sherwood Botsford

Beantwortung der Absicht statt der wörtlichen Frage:

Schauen Sie sich das Skript an. Dadurch erhalten Sie Befehle und deren Ausgabe. Beachten Sie, dass dies kein Allheilmittel ist, da Befehle, die die Cursorpositionierung verwenden, später schwer zu entschlüsseln sind.

Namensskript - Typoskript der Terminalsitzung erstellen

Synopsis-Skript [-a] [-c BEFEHL] [-f] [-q] [-t] [Datei]

Beschreibung Skript erstellt ein Typoskript für alles, was auf Ihrem Terminal gedruckt wird. Es ist nützlich für Studenten, die eine Hardcopy-Aufzeichnung einer interaktiven Sitzung als Beleg für eine Aufgabe benötigen, da die Typoscript-Datei später mit lpr (1) ausgedruckt werden kann.

Wenn die Argumentdatei angegeben ist, speichert das Skript alle Dialoge in der Datei. Wird kein Dateiname angegeben, wird das Typoskript im FileScript gespeichert.

Optionen:

 -a' Append the output to file or typescript, retaining the priorcontents. 

-c BEFEHL Führt den BEFEHL statt einer interaktiven Shell aus. Dies macht es einem Skript leicht, die Ausgabe eines Programms zu erfassen, das sich anders verhält, wenn sein Standardwert kein tty ist. -f 'Ausgabe nach jedem Schreibvorgang leeren. Das ist gut für die Telekooperation: Eine Person macht "mkfifo foo"; script -f foo 'und ein anderer können in Echtzeit überwachen, was mit' cat foo 'gemacht wird.

-q 'Sei ruhig.

-t 'Timing-Daten als Standardfehler ausgeben. Diese Daten enthalten zwei Felder, die durch ein Leerzeichen getrennt sind. Das erste Feld gibt an, wie viel Zeit seit der letzten Ausgabe vergangen ist. Das zweite Feld gibt an, wie viele Zeichen diesmal ausgegeben wurden. Diese Informationen können verwendet werden, um Typoskripte mit realistischer Typisierung und Ausgabeverzögerungen wiederzugeben.

Das Skript endet, wenn die gegabelte Shell beendet wird (ein Control-D zum Verlassen der Bourne-Shell (sh (1)) und Exit, Logout oder Control-D (falls ignoreeof nicht gesetzt ist) für die C-Shell, csh (1). ).

Bestimmte interaktive Befehle, z. B. vi (1), erzeugen einen Abfall in der Typoskriptdatei. Das Skript funktioniert am besten mit Befehlen, die den Bildschirm nicht beeinflussen. Die Ergebnisse sollen ein Hardcopy-Terminal emulieren. ...

Suchen Sie nach "Man Script" bei Google. Wenn Sie ein bestimmtes Betriebssystem haben, schließen Sie das ein. Dies ist die Linux-Version, aber es gibt fast identische Versionen für * BSD, Mac. Wahrscheinlich gibt es auch Windows-Ports.

Nicht wirklich sehr nützlich, aber danke für die Mühe. Ich möchte nur die Historie der von mir ausgeführten Befehle, nicht die Ausgaben. Ich möchte nicht mehr Komplexitätsebenen in etwas einführen, das einfach sein sollte. Fidel vor 5 Jahren 0
1
Fidel

Aus irgendeinem Grund, den ich nicht verstehen kann, funktioniert das:

export HISTFILE_NEW="$HOME/HISTORIES/bash_history_$(basename $(tty))_$(date '+%Y-%m-%d_%H-%M-%S_%Z')" export HISTCONTROL=ignoreboth export HISTFILESIZE=10000 export HISTSIZE=10000 shopt -s histappend PROMPT_COMMAND="history -w $HISTFILE_NEW; $PROMPT_COMMAND" 

Während dies nicht tut

export HISTFILE="$HOME/HISTORIES/bash_history_$(basename $(tty))_$(date '+%Y-%m-%d_%H-%M-%S_%Z')" export HISTCONTROL=ignoreboth export HISTFILESIZE=10000 export HISTSIZE=10000 shopt -s histappend PROMPT_COMMAND="history -a; $PROMPT_COMMAND" 

Natürlich ist die erste Lösung langsamer als die theoretisch gute (die zweite), da die gesamte Historie jedes Mal gespeichert wird, wenn ein neuer Befehl geschrieben wird.

Wenn also jemand weiß, warum dies der Fall ist und wie dies gelöst werden könnte, wäre ich sehr dankbar.