Apakah ada cara untuk mengatur ukuran daftar riwayat di bash menjadi lebih dari 5000 baris?

25

Tidak peduli berapa banyak saya mengatur HISTSIZEvariabel lingkungan menjadi lebih besar dari 5000, ketika mencetak daftar sejarah dengan historybuiltin, itu hanya mencetak 5.000 perintah terakhir. Saya memerlukan itu karena saya sering memiliki yang besar .bash_historyyang melebihi 5000 baris, dan kadang-kadang seseorang perlu mengatasi perintah awal dengan menekan Ctrl-R, tetapi jika perintah itu lebih dari 5000 perintah sebelumnya, saya tidak dapat mengaksesnya menggunakan mekanisme itu. Saya tahu saya bisa menggunakan greppada .bash_history, tapi saya pikir Ctrl-Rmekanismenya akan jauh lebih cepat (dan nyaman). Saya menggunakan gnu bash versi 4.1.

Itu adalah konten lengkap file .bashrc saya:

    #!/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
sumber
Saya tidak dapat mereproduksi ini dengan bash 4.1 atau 4.2, HISTSIZE=9999 HISTFILESIZE=999diatur .bashrc, dan 6.000 baris yang .bash_historysemuanya muncul di output history. Ceritakan versi bash Anda dan dari mana Anda mendapatkannya, dan konten lengkap Anda .bashrc.
Gilles 'SO- stop being evil'
terima kasih atas jawabannya, tetapi bagaimana .bash_history Anda 6000-line dan sementara itu HISTFILESIZE = 999? Saya menggunakan GNU bassh versi 4.1
Marwan Tanager
shopt -s histappend HISTSIZE = 50000 HISTFILESIZE = 500000
Marwan Tanager
Maaf, itu salah ketik: Saya pernah HISTFILESIZE=9999. Itu .bash_historysecara artifisial dibangun untuk pengujian (saya tidak ingin mengetikkan 6000 perintah pada prompt), tetapi bash tidak menyimpannya dengan benar saat keluar. Harap salin dan tempelkan sepenuhnya .bashrcpertanyaan Anda.
Gilles 'SO- stop being evil'
Jika Anda melakukan history | wc -l, berapa banyak baris yang ditampilkan?
Pos Tim

Jawaban:

16

Ini adalah kode aktual yang memuat sejarah (dari bashhist.csekitar baris 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 ();
    }
}

Jika nilai-nilai HISTSIZEdan HISTFILESIZEdiatur, mereka akan digunakan.

Readline, pustaka yang benar-benar menangani pengeditan input / garis dan riwayat memang menawarkan fasilitas untuk membatasi seberapa besar penyangga sejarah dapat tumbuh. Namun, Bash tidak menempatkan langit-langit yang keras di mana nilai-nilai yang lebih besar akan diabaikan, setidaknya yang bisa saya temukan.

Edit

Dari komentar , readlinememang pelakunya. Saya melihat (agak bodoh) pada parameter fungsional:

ada variabel yang disebut histori-ukuran yang dapat dibaca dari file inputrc. variabel itu menetapkan jumlah maksimum entri riwayat yang disimpan dalam daftar riwayat. Saya memeriksa nilainya di file inputrc lokal saya untuk menemukannya sama dengan 5000. Mengaturnya ke nilai yang lebih besar memecahkan masalah.

Pos Tim
sumber
jika tidak menempatkan langit-langit, lalu mengapa menetapkan HISTSIZE ke nilai lebih dari 5000 tidak berpengaruh pada ukuran daftar riwayat setelah memulai kembali shell? Jika Anda memiliki file histori dengan ukuran lebih besar dari 5000 baris coba atur HISTSIZE di .bashrc ke nilai lebih dari 5000, kemudian restart shell dan jalankan histori | wc -l. Anda akan melihat bahwa daftar riwayat kurang dari atau sama dengan 5000 terlepas dari HISTSIZE. Namun, menetapkan HISTSIZE ke nilai apa pun yang kurang dari 5000 akan menghasilkan efek yang terlihat menggunakan eksperimen yang sama.
Marwan Tanager
3
Membaca dokumen GNU readline libraryatin, ternyata Anda benar. ada variabel yang disebut histori-ukuran yang dapat dibaca dari file inputrc. variabel itu menetapkan jumlah maksimum entri riwayat yang disimpan dalam daftar riwayat. Saya memeriksa nilainya di file inputrc lokal saya untuk menemukannya sama dengan 5000. Mengaturnya ke nilai yang lebih besar memecahkan masalah. Terima kasih atas wawasannya :-)
Marwan Tanager
@Marwan Keren :) Saya pikir itu history-sizeadalah sesuatu yang disahkan (dari RL changelog) ke fungsi di readline yang akhirnya dipanggil oleh bash. Sepertinya kita sudah memikirkannya bersama.
Tim Post
7

Riwayat Anda terpotong saat HISTSIZE pertama kali diatur, jadi jika disetel ke 5000 lebih awal di ~ / .bashrc Anda, atau di bashrc seluruh sistem di / etc , Anda perlu berkomentar.

Emil Mikulic
sumber
5

Coba keduanya HISTFILESIZEdan HISTSIZE.

ztank1013
sumber
Saya menetapkan HISTFILESIZE menjadi 50000. Masalahnya adalah dengan HISTSIZE yang menentukan baris 'HISTSIZE' terakhir di .bash_history yang akan dimuat ke dalam memori saat memulai bash dan di mana Anda dapat menggunakan mekanisme ctrl-r.
Marwan Tanager
Setelah Anda login jika Anda mengetik echo "$HISTSIZE $HISTFILESIZE" apa yang Anda lihat?
ztank1013
Ini menghasilkan: "50000 500000"
Marwan Tanager
3

Saya memiliki masalah yang sama (atau serupa), tetapi inputrc baik-baik saja. Dalam kasus saya, satu-satunya hal yang berhasil adalah mengomentariHISTSIZE=1000 dan HISTFILESIZE=2000dalam persediaan saya ~/.bashrc- meskipun saya mengganti vars nanti dalam file yang sama!

perlakukan mod Anda dengan baik
sumber
2

Mengubah baris-baris ini di ~/.bashrcperbaiki untuk saya:

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

HISTFILESIZE=2000

Setelah itu simpan file dan muat ulang file bashrc

$ . ~/.bashrc
javeed shakeel
sumber
1

Saya pikir Anda mungkin memukul langit-langit sejarah pada OS Anda untuk HISTSIZE. Dari halaman manual untuk fc / history di Solaris 10 (menjalankan KSH):

[menggunting]

/ usr / bin / fc

Utilitas fc mencantumkan atau mengedit dan menjalankan kembali, perintah yang sebelumnya dimasukkan ke sh interaktif.

Daftar sejarah perintah merujuk perintah dengan angka. Nomor pertama dalam daftar dipilih secara sewenang-wenang. Hubungan nomor dengan perintahnya tidak akan berubah kecuali ketika pengguna login dan tidak ada proses lain yang mengakses daftar, di mana sistem dapat mengatur ulang penomoran untuk memulai perintah tertua yang disimpan di nomor lain (biasanya 1) . Ketika angka mencapai nilai dalam HISTSIZE atau 32767 (mana yang lebih besar), shell dapat membungkus angka-angka, memulai perintah berikutnya dengan angka yang lebih rendah (biasanya 1). Namun, meskipun pembungkus angka opsional ini, fc akan mempertahankan urutan urutan waktu dari perintah. Misalnya, jika empat perintah secara berurutan diberi angka 32 766, 32 767, 1 (dibungkus),

[menggunting]

yang menyiratkan bahwa perintah fc dapat menangani hingga 32767 entri dalam file histori, menjadikannya pagu yang keras untuk jumlah perintah yang disimpan dalam file histori. Tentu saja YMMV, tapi saya pikir Anda bisa berkonsultasi dengan halaman dokumentasi / manual OS Anda tentang masalah ini. 0,02 saya ...

FanDeLaU
sumber