Gibt es eine Möglichkeit, die Größe der Verlaufsliste in Bash auf mehr als 5000 Zeilen festzulegen?

25

Egal wie viel ich die HISTSIZEUmgebungsvariable auf größer als 5000 einstelle , wenn ich die Verlaufsliste mit dem historyeingebauten Befehl drucke, werden nur die letzten 5000 Befehle gedruckt. Ich brauche das, weil ich oft eine große .bash_historyZahl habe, die 5000 Zeilen überschreitet, und manchmal muss man einen frühen Befehl durch Drücken von ansprechen Ctrl-R, aber wenn dieser Befehl mehr als 5000 Befehle früher ist, kann ich mit diesem Mechanismus nicht darauf zugreifen. Ich weiß , ich kann grepauf das .bash_history, aber ich denke , dass der Ctrl-RMechanismus wäre viel schneller (und praktisch). Ich benutze Gnu Bash Version 4.1.

Das ist der vollständige Inhalt meiner .bashrc-Datei:

    #!/bin/bash
    # ~/.bashrc: executed by bash(1) for non-login shells.
    # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
    # for examples

    # If not running interactively, don't do anything
    [ -z "$PS1" ] && return

    # don't put duplicate lines in the history. See bash(1) for more options
    # ... or force ignoredups and ignorespace
    #HISTCONTROL=ignoredups:ignorespace:erasedups

    # append to the history file, don't overwrite it
    shopt -s histappend

    # for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
    HISTSIZE=50000
    HISTFILESIZE=500000

    # check the window size after each command and, if necessary,
    # update the values of LINES and COLUMNS.
    shopt -s checkwinsize

    # make less more friendly for non-text input files, see lesspipe(1)
    [ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

    # set variable identifying the chroot you work in (used in the prompt below)
    if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
        debian_chroot=$(cat /etc/debian_chroot)
    fi

    # set a fancy prompt (non-color, unless we know we "want" color)
    case "$TERM" in
        xterm-color) color_prompt=yes;;
    esac

    # uncomment for a colored prompt, if the terminal has the capability; turned
    # off by default to not distract the user: the focus in a terminal window
    # should be on the output of commands, not on the prompt
    #force_color_prompt=yes

    if [ -n "$force_color_prompt" ]; then
        if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
        # We have color support; assume it's compliant with Ecma-48
        # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
        # a case would tend to support setf rather than setaf.)
        color_prompt=yes

        else
        color_prompt=

        fi
    fi

    if [ "$color_prompt" = yes ]; then
        PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\         [\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
    else
        PS1='${debian_chroot:+($debian_chroot)}\@-\u@\h:\w\$ '
    fi
    unset color_prompt force_color_prompt

    # If this is an xterm set the title to user@host:dir
    case "$TERM" in
    xterm*|rxvt*)
        PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
        ;;
    *)
        ;;
    esac

    # enable color support of ls and also add handy aliases
    if [ -x /usr/bin/dircolors ]; then
        test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval    "$(dircolors -b)"
        alias ls='ls --color=auto'
        #alias dir='dir --color=auto'
        #alias vdir='vdir --color=auto'

        alias grep='grep --color=auto'
        alias fgrep='fgrep --color=auto'
        alias egrep='egrep --color=auto'
    fi

    # some more ls aliases
    alias ll='ls -alF'
    alias la='ls -A'
    alias l='ls -CF'

    # Alias definitions.
    # You may want to put all your additions into a separate file like
    # ~/.bash_aliases, instead of adding them here directly.
    # See /usr/share/doc/bash-doc/examples in the bash-doc package.

    if [ -f ~/.bash_aliases ]; then
        . ~/.bash_aliases
    fi

    # enable programmable completion features (you don't need to enable
    # this, if it's already enabled in /etc/bash.bashrc and /etc/profile
    # sources /etc/bash.bashrc).
    if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
        . /etc/bash_completion
    fi
Marwan Tanager
quelle
Ich kann dies nicht mit Bash 4.1 oder 4.2 reproduzieren, HISTSIZE=9999 HISTFILESIZE=999die in .bashrcund eine 6000-Zeile gesetzt sind, die .bash_historyalle in der Ausgabe von auftauchen history. Sagen Sie uns Ihre Version von Bash und woher Sie es haben, und den vollständigen Inhalt Ihrer .bashrc.
Gilles 'SO- hör auf böse zu sein'
danke für die antwort, aber wie ist deine .bash_history 6000-zeilig und mittlerweile HISTFILESIZE = 999? Ich benutze GNU Bassh Version 4.1
Marwan Tanager
shopt -s histappend HISTSIZE = 50000 HISTFILESIZE = 500000
Marwan Tanager
Entschuldigung, das war ein Tippfehler: Ich hatte HISTFILESIZE=9999. Das .bash_historywurde für den Test künstlich konstruiert (ich wollte nicht 6000 Befehle an der Eingabeaufforderung eingeben), aber bash speichert es beim Beenden ordnungsgemäß. Bitte kopieren und fügen Sie Ihren vollständigen Text .bashrcin die Frage ein.
Gilles 'SO - hör auf böse zu sein'
Wenn Sie eine machen history | wc -l, wie viele Zeilen werden angezeigt?
Tim Post

Antworten:

16

Dies ist der eigentliche Code, der den Verlauf lädt (ab bashhist.cZeile 260):

/* Load the history list from the history file. */
void

load_history ()
{
  char *hf;

  /* Truncate history file for interactive shells which desire it.
     Note that the history file is automatically truncated to the
     size of HISTSIZE if the user does not explicitly set the size
     differently. */
  set_if_not ("HISTSIZE", "500");
  sv_histsize ("HISTSIZE");

  set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
  sv_histsize ("HISTFILESIZE");

  /* Read the history in HISTFILE into the history list. */
  hf = get_string_value ("HISTFILE");

  if (hf && *hf && file_exists (hf))
    {
      read_history (hf);
      using_history ();
      history_lines_in_file = where_history ();
    }
}

Wenn die Werte von HISTSIZEund gesetzt HISTFILESIZEsind, werden sie verwendet.

Readline, die Bibliothek, die die Eingabe / Zeilenbearbeitung und den Verlauf verwaltet , bietet Funktionen, mit denen festgelegt werden kann, wie groß der Verlaufspuffer werden kann. Bash legt jedoch keine feste Obergrenze fest, an der Werte, die größer sind, ignoriert werden, zumindest, die ich finden konnte.

Bearbeiten

Aus Kommentaren ging readlinein der Tat der Täter hervor. Ich habe (ziemlich dumm) auf funktionale Parameter geschaut:

Es gibt eine Variable namens history-size, die aus der inputrc-Datei gelesen werden kann. Diese Variable legt die maximale Anzahl der in der Verlaufsliste gespeicherten Verlaufseinträge fest. Ich habe den Wert in meiner lokalen inputrc-Datei auf 5000 überprüft. Ein höherer Wert hat das Problem behoben.

Tim Post
quelle
Wenn dadurch keine Obergrenze festgelegt wird, hat das Festlegen von HISTSIZE auf einen Wert größer als 5000 keine Auswirkung auf die Größe der Verlaufsliste nach dem Neustart der Shell. Wenn Sie eine Verlaufsdatei mit einer Größe von mehr als 5000 Zeilen haben, setzen Sie HISTSIZE in .bashrc auf einen Wert größer als 5000, starten Sie die Shell neu und führen Sie den Verlauf aus wc -l. Sie sehen, dass die Verlaufsliste ungeachtet von HISTSIZE kleiner oder gleich 5000 ist. Wenn Sie jedoch HISTSIZE auf einen Wert unter 5000 einstellen, wird bei Verwendung desselben Experiments ein sichtbarer Effekt erzielt.
Marwan Tanager
3
Beim Lesen der Dokumentation zur GNU-Readline-Bibliothek stellte sich heraus, dass Sie Recht haben. Es gibt eine Variable namens history-size, die aus der inputrc-Datei gelesen werden kann. Diese Variable legt die maximale Anzahl der in der Verlaufsliste gespeicherten Verlaufseinträge fest. Ich habe den Wert in meiner lokalen inputrc-Datei auf 5000 überprüft. Ein höherer Wert hat das Problem behoben. Vielen Dank für die Einblicke :-)
Marwan Tanager
@ Marwan Awesome :) Ich dachte, dass dies history-sizeetwas war, das (aus dem RL-Changelog) an die Funktionen in der Readline übergeben wurde, die letztendlich von bash aufgerufen wurden. Sieht so aus, als hätten wir es zusammen herausgefunden.
Tim Post
7

Ihr Verlauf wird abgeschnitten, wenn HISTSIZE zum ersten Mal festgelegt wird. Wenn er also in Ihrem ~ / .bashrc oder im systemweiten bashrc in / etc auf 5000 festgelegt ist, müssen Sie diese auskommentieren .

Emil Mikulic
quelle
5

Probieren Sie beides HISTFILESIZEund HISTSIZE.

ztank1013
quelle
Ich habe HISTFILESIZE auf 50000 gesetzt. Das Problem liegt bei HISTSIZE, das die letzten 'HISTSIZE'-Zeilen in .bash_history bestimmt, die beim Starten von bash in den Speicher geladen werden und für die Sie den ctrl-r-Mechanismus verwenden können.
Marwan Tanager
Sobald Sie sich eingeloggt haben, wenn Sie tippen, echo "$HISTSIZE $HISTFILESIZE" was sehen Sie?
ztank1013
Es produziert: "50000 500000"
Marwan Tanager
3

Ich hatte das gleiche (oder ein ähnliches) Problem, aber inputrc war in Ordnung. In meinem Fall funktionierte das einzige, was auskommentierte HISTSIZE=1000und sich HISTFILESIZE=2000in meinem Bestand befand ~/.bashrc- obwohl ich diese Variablen später in derselben Datei überschrieb!

Behandle deine Mods gut
quelle
2

Das Ändern dieser Zeilen hat ~/.bashrces für mich behoben:

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=5000  

HISTFILESIZE=2000

Speichern Sie anschließend die Datei und laden Sie die bashrc- Datei erneut

$ . ~/.bashrc
javeed shakeel
quelle
1

Ich denke, Sie könnten eine Geschichtsobergrenze für Ihr Betriebssystem für das HISTSIZE erreichen. Auf der Manpage für fc / history in Solaris 10 (mit KSH):

[snip]

/ usr / bin / fc

Das Dienstprogramm fc listet Befehle auf oder bearbeitet sie und führt sie erneut aus, die zuvor in ein interaktives sh eingegeben wurden.

Die Befehlsverlaufsliste verweist auf Befehle nach Nummer. Die erste Nummer in der Liste wird willkürlich ausgewählt. Das Verhältnis einer Nummer zu ihrem Befehl ändert sich nur, wenn sich der Benutzer anmeldet und kein anderer Prozess auf die Liste zugreift. Zu diesem Zeitpunkt setzt das System möglicherweise die Nummerierung zurück, um den ältesten gespeicherten Befehl bei einer anderen Nummer zu starten (normalerweise 1). . Wenn die Zahl den Wert in HISTSIZE oder 32767 erreicht (je nachdem, welcher Wert größer ist), kann die Shell die Zahlen umbrechen und den nächsten Befehl mit einer niedrigeren Zahl beginnen (normalerweise 1). Trotz dieses optionalen Zeilenumbruchs behält fc die zeitliche Reihenfolge der Befehle bei. Wenn beispielsweise vier aufeinanderfolgende Befehle die Nummern 32 766, 32 767, 1 (umbrochen) erhalten,

[snip]

Dies impliziert, dass der Befehl fc bis zu 32767 Einträge in der Verlaufsdatei adressieren kann, was ihn zu einer festen Obergrenze für die Anzahl der in der Verlaufsdatei gespeicherten Befehle macht. Natürlich YMMV, aber ich denke, Sie können diesbezüglich die Dokumentation / Manpages Ihres Betriebssystems konsultieren. Meine 0,02 ...

FanDeLaU
quelle