Czy istnieje sposób, aby ustawić rozmiar listy historii w bash na ponad 5000 linii?

25

Bez względu na to, o ile ustawiłem HISTSIZEzmienną środowiskową na większą niż 5000, podczas drukowania listy historii z historywbudowanym drukuje tylko ostatnie 5000 poleceń. Potrzebuję tego, ponieważ często mam dużą, .bash_historyktóra przekracza 5000 linii, a czasami trzeba odpowiedzieć na wczesne polecenie, naciskając Ctrl-R, ale jeśli to polecenie jest więcej niż 5000 poleceń wcześniej, nie mogę uzyskać do niego dostępu za pomocą tego mechanizmu. Wiem, że mogę korzystać grepz .bash_history, ale myślę, że Ctrl-Rmechanizm byłby znacznie szybszy (i wygodny). Używam gnu bash w wersji 4.1.

To jest pełna zawartość mojego pliku .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
źródło
Nie mogę tego odtworzyć z HISTSIZE=9999 HISTFILESIZE=999ustawioną w bash 4.1 lub 4.2 wersją .bashrci wersją 6000, .bash_historyz których wszystkie pojawiają się w wynikach history. Powiedz nam, jaką masz wersję bash i skąd ją masz, oraz pełną treść swojej .bashrc.
Gilles „SO- przestań być zły”
dziękuję za odpowiedź, ale jak twoja .bash_history ma 6000 linii, a tymczasem HISTFILESIZE = 999? Używam GNU Bassh w wersji 4.1
Marwan Tanager
shopt -s histappend HISTSIZE = 50000 HISTFILESIZE = 500000
Marwan Tanager,
Przepraszam, to była literówka: miałem HISTFILESIZE=9999. .bash_historyZostał sztucznie skonstruowany do badania (nie chciałem wpisać 6000 w wierszu poleceń), ale robi bash zapisać go prawidłowo na wyjściu. Skopiuj i wklej swój pełny .bashrcdo pytania.
Gilles „SO- przestań być zły”
Jeśli to zrobisz history | wc -l, ile linii zostanie pokazanych?
Tim Post

Odpowiedzi:

16

To jest rzeczywisty kod, który ładuje historię (z bashhist.cokoło linii 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 ();
    }
}

Jeśli zostaną ustawione wartości HISTSIZEi HISTFILESIZE, zostaną one użyte.

Readline, biblioteka, która faktycznie obsługuje edytowanie danych wejściowych / linii i historię , oferuje możliwości ograniczenia wielkości bufora historii. Jednak Bash nie stawia na tym twardego pułapu, w którym wartości większe byłyby ignorowane, przynajmniej takie, które mogłem znaleźć.

Edytować

Z uwagi , readlinebył rzeczywiście sprawcą. Patrzyłem (raczej głupio) na parametry funkcjonalne:

istnieje zmienna o nazwie history-size, którą można odczytać z pliku inputrc. ta zmienna określa maksymalną liczbę pozycji historii zapisanych na liście historii. Sprawdziłem, czy wartość w moim lokalnym pliku inputrc jest równa 5000. Ustawienie większej wartości rozwiązało problem.

Tim Post
źródło
jeśli nie stawia pułapu, to dlaczego ustawienie HISTSIZE na wartość większą niż 5000 nie ma wpływu na rozmiar listy historii po zrestartowaniu powłoki? Jeśli masz plik historii o rozmiarze większym niż 5000 linii, spróbuj ustawić HISTSIZE w .bashrc na wartość większą niż 5000, a następnie zrestartuj powłokę i uruchom historię | wc -l. Zobaczysz, że lista historii jest mniejsza lub równa 5000 niezależnie od HISTSIZE. Jednak ustawienie HISTSIZE na dowolną wartość mniejszą niż 5000 dałoby widoczny efekt przy użyciu tego samego eksperymentu.
Marwan Tanager,
3
Czytając dokumentację biblioteki readline GNU, okazało się, że masz rację. istnieje zmienna o nazwie history-size, którą można odczytać z pliku inputrc. ta zmienna określa maksymalną liczbę pozycji historii zapisanych na liście historii. Sprawdziłem, czy wartość w moim lokalnym pliku inputrc jest równa 5000. Ustawienie większej wartości rozwiązało problem. Dzięki za wgląd :-)
Marwan Tanager,
@Marwan Awesome :) Myślałem, że history-sizeto coś zostało przekazane (z dziennika zmian RL) do funkcji w readline, które ostatecznie zostały wywołane przez bash. Wygląda na to, że wspólnie to wymyśliliśmy.
Tim Post
7

Twoja historia jest obcinana przy pierwszym ustawieniu HISTSIZE, więc jeśli jest ustawiona na 5000 wcześniej w ~ / .bashrc lub w ogólnosystemowym bashrc w / etc , musisz je skomentować.

Emil Mikulic
źródło
5

Spróbuj obu HISTFILESIZEi HISTSIZE.

ztank1013
źródło
Ustawiłem HISTFILESIZE na 50000. Problem dotyczy HISTSIZE, który określa ostatnie wiersze „HISTSIZE” w .bash_history, które mają zostać załadowane do pamięci podczas uruchamiania bash, i na których można użyć mechanizmu ctrl-r.
Marwan Tanager,
Po zalogowaniu się, jeśli wpiszesz echo "$HISTSIZE $HISTFILESIZE" to, co widzisz?
ztank1013,
Wytwarza: „50000 500000”
Marwan Tanager,
3

Miałem ten sam (lub podobny) problem, ale inputrc było w porządku. W moim przypadku, jedyną rzeczą, która pracowała była zakomentowanie HISTSIZE=1000i HISTFILESIZE=2000w moim stanie ~/.bashrc- mimo że było nadrzędne tych vars później w tym samym pliku!

traktujcie dobrze swoje mody
źródło
2

Zmiana tych wierszy ~/.bashrcnaprawiła to dla mnie:

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

HISTFILESIZE=2000

Następnie zapisz plik i załaduj ponownie plik bashrc

$ . ~/.bashrc
javeed shakeel
źródło
1

Wydaje mi się, że w HISTSIZE osiągasz pułap historii systemu operacyjnego. Ze strony podręcznika użytkownika dla fc / history w Solarisie 10 (z systemem KSH):

[fantastyczna okazja]

/ usr / bin / fc

Narzędzie fc wyświetla lub edytuje i ponownie wykonuje polecenia, polecenia wcześniej wprowadzone do interaktywnego sh.

Lista historii poleceń odwołuje się do poleceń według numeru. Pierwszy numer na liście jest wybierany arbitralnie. Związek numeru z jego poleceniem nie zmieni się, chyba że użytkownik zaloguje się i żaden inny proces nie uzyska dostępu do listy, w którym to czasie system może zresetować numerację, aby uruchomić najstarsze zachowane polecenie pod innym numerem (zwykle 1) . Gdy liczba osiągnie wartość w HISTSIZE lub 32767 (w zależności od tego, która wartość jest większa), powłoka może zawijać liczby, rozpoczynając następne polecenie niższą liczbą (zwykle 1). Jednak pomimo tego opcjonalnego zawijania liczb, fc zachowa sekwencję czasową poleceń. Na przykład, jeśli cztery kolejne polecenia otrzymają numery 32 766, 32 767, 1 (zapakowane),

[fantastyczna okazja]

co oznacza, że ​​komenda fc może adresować do 32767 pozycji w pliku historii, co stanowi twardy pułap dla liczby poleceń przechowywanych w pliku historii. Oczywiście YMMV, ale myślę, że możesz zajrzeć do dokumentacji systemu operacyjnego / stron podręcznika w tej sprawie. Mój 0,02 ...

FanDeLaU
źródło