Existe uma maneira de definir o tamanho da lista do histórico no bash para mais de 5000 linhas?

25

Não importa quanto eu defina a HISTSIZEvariável de ambiente maior que 5000, ao imprimir a lista de histórico com o historybuilt-in, ela imprime apenas os últimos 5000 comandos. Eu preciso disso porque geralmente tenho um grande .bash_historyque excede 5000 linhas e, às vezes, é necessário endereçar um comando inicial pressionando Ctrl-R, mas se esse comando tiver mais de 5000 comandos anteriores, não posso acessá-lo usando esse mecanismo. Eu sei que posso usar grepno .bash_history, mas acho que o Ctrl-Rmecanismo seria muito mais rápido (e conveniente). Eu uso o gnu bash versão 4.1.

Esse é o conteúdo completo do meu arquivo .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
fonte
Não consigo reproduzir isso com o bash 4.1 ou 4.2, HISTSIZE=9999 HISTFILESIZE=999definido .bashrc, e uma linha de 6000, .bash_historyque aparece na saída de history. Conte-nos sua versão do bash, de onde você o obteve e todo o conteúdo do seu .bashrc.
Gilles 'SO- stop be evil'
obrigado pela resposta, mas como seu .bash_history é de 6000 linhas e, enquanto isso, HISTFILESIZE = 999? Eu uso o GNU bassh versão 4.1
Marwan Tanager
shopt -s histappend HISTSIZE = 50000 HISTFILESIZE = 500000
Marwan Tanager
Desculpe, isso foi um erro de digitação: eu tive HISTFILESIZE=9999. O .bash_historyfoi construído artificialmente para o teste (eu não queria digitar 6000 comandos no prompt), mas o bash o salva corretamente na saída. Copie e cole o seu total .bashrcna pergunta.
Gilles 'SO- stop be evil'
Se você faz um history | wc -l, quantas linhas são mostradas?
Tim Post

Respostas:

16

Este é o código real que carrega o histórico (da bashhist.clinha 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 ();
    }
}

Se os valores de HISTSIZEe HISTFILESIZEestiverem definidos, eles serão usados.

O Readline, a biblioteca que realmente lida com edição e histórico de entrada / linha , oferece facilidades para limitar o tamanho do buffer do histórico. No entanto, o Bash não coloca um teto rígido sobre isso onde valores maiores seriam ignorados, pelo menos que eu pudesse encontrar.

Editar

De comentários , readlinefoi realmente o culpado. Eu estava olhando (de maneira tola) para parâmetros funcionais:

existe uma variável chamada tamanho do histórico que pode ser lida no arquivo inputrc. essa variável define o número máximo de entradas do histórico salvas na lista de histórico. Eu verifiquei o valor no meu arquivo inputrc local para encontrar igual a 5000. A configuração para um valor maior resolveu o problema.

Tim Post
fonte
se não colocar um teto, por que definir HISTSIZE com um valor maior que 5000 não afeta o tamanho da lista de históricos depois de reiniciar o shell? Se você tiver um arquivo de histórico com tamanho maior que 5000 linhas, tente definir HISTSIZE em .bashrc para um valor maior que 5000, reinicie o shell e execute o histórico | wc -l. Você verá que a lista do histórico é menor ou igual a 5000, independentemente de HISTSIZE. No entanto, definir HISTSIZE para qualquer valor menor que 5000 produziria um efeito visível usando o mesmo experimento.
Marwan Tanager
3
Lendo a documentação da biblioteca GNU readline, descobriu-se que você está certo. existe uma variável chamada tamanho do histórico que pode ser lida no arquivo inputrc. essa variável define o número máximo de entradas do histórico salvas na lista de histórico. Eu verifiquei o valor no meu arquivo inputrc local para encontrar igual a 5000. A configuração para um valor maior resolveu o problema. Graças para os insights :-)
Marwan Tanager
@ Marwan Awesome :) Eu pensei que history-sizeera algo que foi passado (do changelog RL) para as funções na linha de leitura que, em última análise, foram chamadas pelo bash. Parece que descobrimos juntos.
Tim Post
7

Seu histórico é truncado na primeira vez em que HISTSIZE é definido, portanto, se estiver definido como 5000 no seu ~ / .bashrc ou no bashrc em todo o sistema em / etc , você precisará comentá-los.

Emil Mikulic
fonte
5

Tente ambos HISTFILESIZEe HISTSIZE.

ztank1013
fonte
Defino HISTFILESIZE como 50000. O problema é com HISTSIZE, que determina as últimas linhas 'HISTSIZE' em .bash_history a serem carregadas na memória ao iniciar o bash e nas quais você pode usar o mecanismo ctrl-r.
Marwan Tanager
Depois de fazer login, se você digitar echo "$HISTSIZE $HISTFILESIZE" o que vê?
precisa saber é o seguinte
Produz: "50000 500000"
Marwan Tanager
3

Eu tive o mesmo problema (ou semelhante), mas o inputrc estava bem. No meu caso, a única coisa que funcionou foi comentando HISTSIZE=1000e HISTFILESIZE=2000em meu estoque ~/.bashrc- mesmo que eu estava substituindo os vars mais tarde no mesmo arquivo!

trate bem seus mods
fonte
2

Alterar essas linhas em ~/.bashrccorrigi-lo para mim:

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

HISTFILESIZE=2000

Depois disso, salve o arquivo e recarregue o arquivo bashrc

$ . ~/.bashrc
shakeel javeed
fonte
1

Eu acho que você pode estar atingindo um limite histórico no seu sistema operacional para o HISTSIZE. Na página de manual do fc / history no Solaris 10 (executando o KSH):

[recorte]

/ usr / bin / fc

O utilitário fc lista ou edita e reexecuta comandos previamente inseridos em um sh interativo.

A lista do histórico de comandos faz referência aos comandos por número. O primeiro número da lista é selecionado arbitrariamente. A relação de um número com seu comando não será alterada, exceto quando o usuário efetuar login e nenhum outro processo estiver acessando a lista; nesse momento, o sistema poderá redefinir a numeração para iniciar o comando retido mais antigo em outro número (geralmente 1) . Quando o número atinge o valor em HISTSIZE ou 32767 (o que for maior), o shell pode agrupar os números, iniciando o próximo comando com um número menor (geralmente 1). No entanto, apesar desse agrupamento opcional de números, o fc manterá a sequência de ordem dos tempos dos comandos. Por exemplo, se quatro comandos em sequência receberem os números 32 766, 32 767, 1 (agrupados),

[recorte]

o que implica que o comando fc pode endereçar até 32767 entradas no arquivo de histórico, tornando-o um teto rígido para o número de comandos mantidos no arquivo de histórico. Claro YMMV, mas acho que você pode consultar a documentação / páginas do manual do SO sobre esse assunto. Meu 0,02 ...

FanDeLaU
fonte