Existe-t-il un moyen de définir la taille de la liste d'historique dans bash sur plus de 5 000 lignes?

25

Peu importe à quel point j'ai défini la HISTSIZEvariable d'environnement à une valeur supérieure à 5000, lors de l'impression de la liste d'historique avec la fonction historyintégrée, elle n'imprime que les 5000 dernières commandes. J'ai besoin de cela parce que j'ai souvent un grand .bash_historyqui dépasse 5000 lignes, et parfois il faut adresser une commande précoce en appuyant sur Ctrl-R, mais si cette commande est plus de 5000 commandes plus tôt, je ne peux pas y accéder en utilisant ce mécanisme. Je sais que je peux l'utiliser grepsur le .bash_history, mais je pense que le Ctrl-Rmécanisme serait beaucoup plus rapide (et pratique). J'utilise gnu bash version 4.1.

C'est le contenu complet de mon fichier .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
la source
Je ne peux pas reproduire cela avec bash 4.1 ou 4.2, HISTSIZE=9999 HISTFILESIZE=999installé .bashrc, et une ligne de 6000 lignes .bash_historyqui apparaissent toutes dans la sortie de history. Dites-nous votre version de bash et d'où vous l'avez obtenue, ainsi que le contenu complet de votre .bashrc.
Gilles 'SO- arrête d'être méchant'
merci pour la réponse, mais comment votre .bash_history est de 6000 lignes et en attendant HISTFILESIZE = 999? J'utilise GNU bassh version 4.1
Marwan Tanager
shopt -s histappend HISTSIZE = 50000 HISTFILESIZE = 500000
Marwan Tanager
Désolé, c'était une faute de frappe: je l'avais fait HISTFILESIZE=9999. Le a .bash_historyété construit artificiellement pour le test (je ne voulais pas taper 6000 commandes à l'invite), mais bash l'enregistre correctement à la sortie. Veuillez copier-coller votre intégralité .bashrcdans la question.
Gilles 'SO- arrête d'être méchant'
Si vous faites un history | wc -l, combien de lignes sont affichées?
Tim Post

Réponses:

16

C'est le code réel qui charge l'historique (à partir de la bashhist.cligne 260 environ):

/* 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 les valeurs de HISTSIZEet HISTFILESIZEsont définies, elles seront utilisées.

Readline, la bibliothèque qui gère effectivement entrée / édition de la ligne et l' histoire ne offrent des installations pour mettre un plafond juste la taille de la mémoire tampon de l' histoire peut se développer. Cependant, Bash ne place pas de plafond rigide sur ce point où des valeurs plus grandes seraient ignorées, du moins que je pourrais trouver.

modifier

D'après les commentaires , readlineétait en effet le coupable. Je regardais (plutôt bêtement) les paramètres fonctionnels:

il existe une variable appelée taille d'historique qui peut être lue à partir du fichier inputrc. cette variable définit le nombre maximal d'entrées d'historique enregistrées dans la liste d'historique. J'ai vérifié sa valeur dans mon fichier inputrc local pour la trouver égale à 5000. La définition d'une valeur plus élevée a résolu le problème.

Tim Post
la source
s'il ne place pas de plafond, alors pourquoi définir HISTSIZE sur une valeur supérieure à 5000 n'a aucun effet sur la taille de la liste d'historique après le redémarrage du shell? Si vous avez un fichier historique de taille supérieure à 5000 lignes, essayez de définir HISTSIZE dans .bashrc sur une valeur supérieure à 5000, puis redémarrez le shell et exécutez history | wc -l. Vous verriez que la liste d'historique est inférieure ou égale à 5000 indépendamment de HISTSIZE. Cependant, la définition de HISTSIZE sur une valeur inférieure à 5000 produirait un effet visible en utilisant la même expérience.
Marwan Tanager
3
En lisant la documentation de la bibliothèque GNU readline, il s'est avéré que vous aviez raison. il existe une variable appelée taille d'historique qui peut être lue à partir du fichier inputrc. cette variable définit le nombre maximal d'entrées d'historique enregistrées dans la liste d'historique. J'ai vérifié sa valeur dans mon fichier inputrc local pour la trouver égale à 5000. La définition d'une valeur plus élevée a résolu le problème. Merci pour la perspicacité :-)
Marwan Tanager
@Marwan Awesome :) Je pensais que history-sizec'était quelque chose qui était passé (depuis le changelog RL) aux fonctions de la ligne de lecture qui étaient finalement appelées par bash. On dirait que nous l'avons compris ensemble.
Tim Post
7

Votre historique est tronqué la première fois que HISTSIZE est défini, donc s'il est défini à 5000 plus tôt dans votre ~ / .bashrc, ou dans le bashrc à l'échelle du système dans / etc , vous devez les commenter.

Emil Mikulic
la source
5

Essayez les deux HISTFILESIZEet HISTSIZE.

ztank1013
la source
J'ai défini HISTFILESIZE sur 50000. Le problème est avec HISTSIZE qui détermine les dernières lignes 'HISTSIZE' dans .bash_history à charger en mémoire lors du démarrage de bash et sur lesquelles vous pouvez utiliser le mécanisme ctrl-r.
Marwan Tanager
Une fois connecté, si vous tapez, echo "$HISTSIZE $HISTFILESIZE" que voyez-vous?
ztank1013
Il produit: "50000 500000"
Marwan Tanager
3

J'ai eu le même problème (ou un problème similaire), mais inputrc allait bien. Dans mon cas, la seule chose qui a fonctionné a été de commenter HISTSIZE=1000et HISTFILESIZE=2000dans mon stock ~/.bashrc- même si je remplaçais ces vars plus tard dans le même fichier!

traitez bien vos mods
la source
2

La modification de ces lignes l'a ~/.bashrccorrigé pour moi:

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

HISTFILESIZE=2000

Après cela, enregistrez le fichier et rechargez le fichier bashrc

$ . ~/.bashrc
shakeel javeed
la source
1

Je pense que vous pourriez atteindre un plafond historique sur votre système d'exploitation pour le HISTSIZE. À partir de la page de manuel de fc / history dans Solaris 10 (exécutant KSH):

[couper]

/ usr / bin / fc

L'utilitaire fc répertorie ou modifie et réexécute les commandes précédemment entrées dans un sh interactif.

La liste de l'historique des commandes fait référence aux commandes par numéro. Le premier numéro de la liste est sélectionné arbitrairement. La relation d'un numéro à sa commande ne changera pas, sauf lorsque l'utilisateur se connecte et qu'aucun autre processus n'accède à la liste, auquel cas le système peut réinitialiser la numérotation pour démarrer la commande conservée la plus ancienne à un autre numéro (généralement 1) . Lorsque le nombre atteint la valeur HISTSIZE ou 32767 (selon la valeur la plus élevée), le shell peut encapsuler les nombres, en commençant la commande suivante par un nombre inférieur (généralement 1). Cependant, malgré cet encapsulation facultative des nombres, fc conservera la séquence chronologique des commandes. Par exemple, si quatre commandes consécutives reçoivent les numéros 32 766, 32 767, 1 (encapsulé),

[couper]

ce qui implique que la commande fc peut adresser jusqu'à 32 767 entrées dans le fichier historique, ce qui en fait un plafond difficile pour le nombre de commandes conservées dans le fichier historique. Bien sûr YMMV, mais je pense que vous pouvez consulter la documentation de votre système d'exploitation / pages de manuel à ce sujet. Mon 0,02 ...

FanDeLaU
la source