¿Hay alguna manera de establecer el tamaño de la lista de historial en bash en más de 5000 líneas?

25

No importa cuánto establezca que la HISTSIZEvariable de entorno sea mayor que 5000, cuando imprimo la lista de historial con el historyincorporado, imprime solo los últimos 5000 comandos. Lo necesito porque a menudo tengo un tamaño grande .bash_historyque supera las 5000 líneas, y a veces uno necesita abordar un comando temprano presionando Ctrl-R, pero si ese comando tiene más de 5000 comandos antes, no puedo acceder a él usando ese mecanismo. Sé que puedo utilizar grepen el .bash_history, pero creo que el Ctrl-Rmecanismo sería mucho más rápido (y conveniente). Yo uso gnu bash versión 4.1.

Ese es el contenido completo de mi archivo .bashrc:

    #!/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
fuente
No puedo reproducir esto con bash 4.1 o 4.2, HISTSIZE=9999 HISTFILESIZE=999configurado .bashrc, y una línea de 6000 .bash_historyque se muestran en la salida de history. Cuéntanos tu versión de bash y de dónde la obtuviste, y el contenido completo de tu .bashrc.
Gilles 'SO- deja de ser malvado'
gracias por la respuesta, pero ¿cómo su .bash_history es de 6000 líneas y mientras tanto HISTFILESIZE = 999? Yo uso GNU bassh versión 4.1
Marwan Tanager
shopt -s histappend HISTSIZE = 50000 HISTFILESIZE = 500000
Marwan Tanager
Lo siento, eso fue un error tipográfico: lo hice HISTFILESIZE=9999. Se .bash_historyconstruyó artificialmente para la prueba (no quería escribir 6000 comandos en el indicador), pero bash lo guarda correctamente al salir. Por favor, copie y pegue todo .bashrcen la pregunta.
Gilles 'SO- deja de ser malvado'
Si haces un history | wc -l, ¿cuántas líneas se muestran?
Tim Post

Respuestas:

16

Este es el código real que carga el historial (de bashhist.calrededor de la línea 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 ();
    }
}

Si se establecen los valores de HISTSIZEy HISTFILESIZE, se utilizarán.

Readline, la biblioteca que realmente maneja la edición de entrada / línea y el historial , ofrece facilidades para poner un límite a cuán grande puede crecer el búfer de historial. Sin embargo, Bash no coloca un techo duro en esto donde los valores más grandes serían ignorados, al menos eso podría encontrar.

Editar

De los comentarios , readlinefue de hecho el culpable. Estaba mirando (bastante tontamente) los parámetros funcionales:

hay una variable llamada tamaño de historial que se puede leer desde el archivo inputrc. esa variable establece el número máximo de entradas de historial guardadas en la lista de historial. Verifiqué su valor en mi archivo inputrc local para encontrar que es igual a 5000. Establecerlo en un valor mayor resolvió el problema.

Tim Post
fuente
si no coloca un techo, entonces ¿por qué establecer HISTSIZE en cualquier valor mayor que 5000 no tiene ningún efecto en el tamaño de la lista del historial después de reiniciar el shell? Si tiene un archivo de historial de tamaño superior a 5000 líneas, intente configurar HISTSIZE en .bashrc a un valor superior a 5000, luego reinicie el shell y ejecute el historial | wc -l. Vería que la lista del historial es menor o igual a 5000 independientemente de HISTSIZE. Sin embargo, establecer HISTSIZE en cualquier valor inferior a 5000 produciría un efecto visible utilizando el mismo experimento.
Marwan Tanager
3
Al leer la documentación de la biblioteca de líneas de lectura de GNU, resultó que tienes razón. hay una variable llamada tamaño de historial que se puede leer desde el archivo inputrc. esa variable establece el número máximo de entradas de historial guardadas en la lista de historial. Verifiqué su valor en mi archivo inputrc local para encontrar que es igual a 5000. Establecerlo en un valor mayor resolvió el problema. Gracias por las ideas :-)
Marwan Tanager
@Marwan Awesome :) Pensé que history-sizeera algo que se pasó (del registro de cambios de RL) a las funciones en readline que finalmente fueron llamadas por bash. Parece que lo descubrimos juntos.
Tim Post
7

Su historial se trunca la primera vez que se configura HISTSIZE, por lo que si está configurado en 5000 antes en su ~ / .bashrc, o en el bashrc de todo el sistema en / etc , debe comentarlos.

Emil Mikulic
fuente
5

Prueba ambos HISTFILESIZEy HISTSIZE.

ztank1013
fuente
Configuré HISTFILESIZE para que sea 50000. El problema es con HISTSIZE que determina las últimas líneas 'HISTSIZE' en .bash_history que se cargarán en la memoria al iniciar bash y sobre las cuales puede usar el mecanismo ctrl-r.
Marwan Tanager
Una vez que haya iniciado sesión si escribe, echo "$HISTSIZE $HISTFILESIZE" ¿qué ve?
ztank1013
Produce: "50000 500000"
Marwan Tanager
3

Tuve el mismo problema (o similar), pero inputrc estaba bien. En mi caso, lo único que funcionó fue comentar HISTSIZE=1000y HISTFILESIZE=2000en mi inventario ~/.bashrc, ¡aunque anulé esos vars más adelante en el mismo archivo!

trata bien tus modificaciones
fuente
2

Cambiar estas líneas lo ~/.bashrcarregló para mí:

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

HISTFILESIZE=2000

Después de eso, guarde el archivo y vuelva a cargar el archivo bashrc

$ . ~/.bashrc
Shakeel Javeed
fuente
1

Creo que puede estar alcanzando un límite histórico en su sistema operativo para HISTSIZE. Desde la página de manual para fc / history en Solaris 10 (ejecutando KSH):

[recorte]

/ usr / bin / fc

La utilidad fc enumera o edita y vuelve a ejecutar, comandos ingresados ​​previamente en un sh interactivo.

La lista del historial de comandos hace referencia a los comandos por número. El primer número en la lista se selecciona arbitrariamente. La relación de un número con su comando no cambiará, excepto cuando el usuario inicie sesión y ningún otro proceso esté accediendo a la lista, momento en el cual el sistema puede restablecer la numeración para iniciar el comando retenido más antiguo en otro número (generalmente 1) . Cuando el número alcanza el valor en HISTSIZE o 32767 (el que sea mayor), el shell puede ajustar los números, comenzando el siguiente comando con un número más bajo (generalmente 1). Sin embargo, a pesar de esta envoltura opcional de números, fc mantendrá la secuencia de orden de tiempo de los comandos. Por ejemplo, si cuatro comandos en secuencia reciben los números 32 766, 32 767, 1 (envuelto),

[recorte]

lo que implica que el comando fc puede direccionar hasta 32767 entradas en el archivo de historial, por lo que es un límite máximo para la cantidad de comandos guardados en el archivo de historial. Por supuesto, YMMV, pero creo que puede consultar la documentación de su sistema operativo / páginas de manual sobre este asunto. Mi 0.02 ...

FanDeLaU
fuente