Bash Save History ohne Exit


16

im Linux Ubuntu Bash Terminal. Gibt es eine Möglichkeit, den Bash-Verlauf zu speichern, ohne Exit zu schreiben? Ich habe die Konfiguration auf "HISTCONTROL = erasedups" gesetzt.

was meiner Meinung nach besser funktioniert als ignoriert.

Aus irgendeinem Grund werden die letzten Befehle im Bash-Terminal nur gespeichert, wenn ich "exit" eingebe. Ich bin es gewohnt, einfach auf das Kreuz im Terminalfenster zu klicken, daher ärgere ich mich immer, dass die letzten Befehle beim erneuten Anmelden nicht gespeichert wurden.

Erinnerung: http://www.thegeekstuff.com/2008/08/15-examples-to-master-linux-command-line-history/#more-130


Beim Fernzugriff auf das Terminal von Putty besteht die Möglichkeit, beim Beenden das Fenster Fenster schließen zu wählen: immer. Das spart mir die Geschichte.
ColacX

Antworten:


34

Bash-Geschichte

Alle neuen Befehle, die im aktiven Terminal ausgegeben wurden, können .bash_historymit dem folgenden Befehl an die Datei angehängt werden :

history -a

Das einzige schwierige Konzept zu verstehen ist , dass jedes Endgerät seine eigene bash Geschichte Liste (aus der geladenen .bash_historyDatei , wenn Sie das Terminal öffnen)

Wenn Sie einen neuen Verlauf abrufen möchten, der während der Lebensdauer dieses aktiven Terminals von anderen Terminals geschrieben wurde, können Sie den Inhalt der .bash_history Datei an die Liste des aktiven Bash-Verlaufs anhängen

history -c;history -r

Dadurch wird die aktuelle Verlaufsliste gelöscht, sodass keine wiederholte Liste angezeigt wird, und die Verlaufsdatei wird an die (jetzt leere) Liste angehängt.

Lösung

Sie können die Bash-Variable verwenden PROMPT_COMMAND, um bei jeder neuen Eingabeaufforderung einen Befehl auszugeben (jedes Mal, wenn Sie im Terminal die Eingabetaste drücken).

export PROMPT_COMMAND='history -a'

Dadurch wird jeder Befehl in der Verlaufsdatei aufgezeichnet, sobald er ausgegeben wird.

Ergebnis

Jetzt hat jedes neue Terminal, das Sie öffnen, den Verlauf anderer Terminals, ohne dass Sie exitdiese anderen Terminals benötigen. Dies ist mein bevorzugter Workflow.

Mehr Präzision

Angenommen, Sie haben (aus irgendeinem Grund) zwei Terminals, die Sie gleichzeitig verwenden, und möchten, dass der Verlauf für jeden neuen Befehl zwischen beiden Terminals angezeigt wird.

export PROMPT_COMMAND='history -a;history -c;history -r'

Der Hauptnachteil hierbei ist, dass Sie möglicherweise die Eingabetaste drücken müssen, um PROMPT_COMMAND erneut auszuführen, um den neuesten Verlauf vom gegenüberliegenden Terminal abzurufen.

Sie können sehen, warum diese präzisere Option wahrscheinlich übertrieben ist, aber sie funktioniert für diesen Anwendungsfall.


Das ist so großartig für richtige Workflows ...
Matt


1

Es gibt eine Möglichkeit, Ihren gesamten Bash-Verlauf in einer separaten Datei zu speichern . Wenn Sie jedoch versuchen, den Verlaufsmechanismus zu verwenden, und aus irgendeinem Grund nicht der gesamte Verlauf gespeichert wird, ist dies ein anderes Problem.

So speichern Sie Ihren gesamten Verlauf immer in einer separaten Datei, unabhängig davon, was mit dem Terminal passiert

Ein hier bereitgestelltes Skript erledigt den Trick.

# don't put duplicate lines in the history. See bash(1) for more options
# ... and ignore same sucessive entries.
export HISTCONTROL=ignoreboth

# set the time format for the history file.
export HISTTIMEFORMAT="%Y.%m.%d %H:%M:%S "

# If this is an xterm set the title to user@host:dir
case "$TERM" in
  xterm*|rxvt*)
  # Show the currently running command in the terminal title:
  # http://www.davidpashley.com/articles/xterm-titles-with-bash.html
  show_command_in_title_bar()
  {
    case "$BASH_COMMAND" in
      *\033]0*)
      # The command is trying to set the title bar as well;
      # this is most likely the execution of $PROMPT_COMMAND.
      # In any case nested escapes confuse the terminal, so don't
      # output them.
      ;;
      *)
      if test ! "$BASH_COMMAND" = "log_bash_eternal_history"
      then
        echo -ne "\033]0;$(history 1 | sed 's/^ *[0-9]* *//') :: ${PWD} :: ${USER}@${HOSTNAME}\007"
      fi
      ;;
    esac
  }
  trap show_command_in_title_bar DEBUG
  ;;
  *)
  ;;
esac

log_bash_eternal_history()
{
  local rc=$?
  [[ $(history 1) =~ ^\ *[0-9]+\ +([^\ ]+\ [^\ ]+)\ +(.*)$ ]]
  local date_part="${BASH_REMATCH[1]}"
  local command_part="${BASH_REMATCH[2]}"
  if [ "$command_part" != "$ETERNAL_HISTORY_LAST" -a "$command_part" != "ls" -a "$command_part" != "ll" ]
  then
    echo $date_part $HOSTNAME $rc "$command_part" >> ~/.bash_eternal_history
    export ETERNAL_HISTORY_LAST="$command_part"
  fi
}

PROMPT_COMMAND="log_bash_eternal_history"

Um den Verlaufsbefehl "Jetzt speichern!" Wenn Sie in einem virtuellen Terminalfenster auf das X klicken

Zunächst müssen Sie verstehen, welchen Mechanismus Ihr Emulator für virtuelle Terminals verwendet, um den bashProzess beim Beenden abzubrechen. - Dies hängt davon ab, welchen genauen Terminalemulator Sie verwenden.

Es gibt einige Optionen, die alle UNIX-Signale beinhalten .

  • SIGTERM, SIGINT, SIGQUIT: Das Standardverhalten, wenn Bash eines dieser Signale im interaktiven Modus empfängt, besteht darin, es zu ignorieren, also ist es wahrscheinlich nicht so.

  • SIGHUP: Dieses Signal bewirkt normalerweise, dass Bash ordnungsgemäß beendet wird und eine Bereinigung durchführt. Ich bin mir jedoch nicht sicher, ob bei dieser "Bereinigung" die Verlaufsdatei gespeichert wird. Wahrscheinlich nicht.

  • SIGKILL, SIGSTOP: Es ist für Bash als Userspace-Prozess unmöglich, diese Signale zu ignorieren. Mit diesen Signalen kann der Kernel den Prozess jederzeit gewaltsam beenden oder stoppen. Wenn Ihr VT-Emulator eines davon sendet, können wir es nicht abfangen und vor dem Beenden etwas unternehmen, sodass Sie kein Glück haben.

Einige Referenzen: ServerFault-Frage 337123

Unix-Frage 6332

Interaktive Verwendung des Verlaufs im GNU Bash-Handbuch

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.