Jak: Unlimited Bash / shell shell?

83

Czy istnieje sposób na zdefiniowanie nieograniczonej historii w Bash?

Dragos
źródło

Odpowiedzi:

82

Dodaj to do .bashrc(Linux) lub .bash_profile(MacOS):

export HISTFILESIZE=
export HISTSIZE=

Proszę bardzo, nieograniczona historia. Obecnie mam 27000 wpisów :)

Od man bash:

Jeśli HISTFILESIZEnie jest ustawiony, nie jest wykonywane obcinanie.

Oznacza to, że .bash_historynigdy nie jest obcinany

To samo wydaje się dotyczyć HISTSIZE, chociaż nie mogłem znaleźć tego udokumentowanego.

Kolejną ciekawą funkcją, którą zamierzam wypróbować, jest:

Jeśli HISTTIMEFORMATzmienna jest ustawiona, znaczniki czasu są zapisywane w pliku historii, oznaczone znakiem komentarza historii, dzięki czemu można je zachować w sesjach powłoki, jak poniżej:

export HISTTIMEFORMAT="%F %T "

Daj mi znać, jeśli już tego próbowałeś ...

morgenrot
źródło
3
W rzeczywistości nie działa to w wielu przypadkach, a historia bash wciąż jest obcinana. Zobacz moją odpowiedź poniżej, aby uzyskać bardziej kompletne rozwiązanie.
fotinakis
2
Ostrzeżenie: powoduje to bóle głowy z gdb; jeśli ustawisz HISTSIZEzmienną, przyjmie ona wartość 0, tym samym całkowicie wyłączając rozmiar historii.
Matteo Italia,
2
uwagi: nie potrzebujesz export, HISTFILESIZEjest w liczbie wierszy (nie bajtów), a obcinanie pliku historii następuje po ustawieniu zmiennejHISTFILESIZE (i po wyjściu powłoki). Więc nie ustawiaj go dwukrotnie w pliku konfiguracyjnym o różnych wartościach
vaab
@vaab: jeśli nie eksportuję HISTFILE, nie widzę, co mój plik histologiczny używa „echo $ HISTFILE” w podpowłokach, więc chociaż nie jest to konieczne, może być pomocny i nie wyrządza szkody, którą mogę wykryć.
Jeff Learman
41

(ponowne opublikowanie mojej odpowiedzi z https://stackoverflow.com/a/19533853/128597 )

Po wielu dużych, brzydkich iteracjach i dziwnych przypadkach na przestrzeni lat, teraz mam zwięzłą sekcję mojego .bashrc poświęconą temu.

Najpierw musisz skomentować lub usunąć tę sekcję .bashrc (domyślnie dla Ubuntu). Jeśli tego nie zrobisz, niektóre środowiska (takie jak uruchamianie screensesji) nadal będą obcinać Twoją historię:

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

Po drugie, dodaj to na dole swojego .bashrc:

# Eternal bash history.
# ---------------------
# Undocumented feature which sets the size to "unlimited".
# https://stackoverflow.com/questions/9457233/unlimited-bash-history
export HISTFILESIZE=
export HISTSIZE=
export HISTTIMEFORMAT="[%F %T] "
# Change the file location because certain bash sessions truncate .bash_history file upon close.
# http://superuser.com/questions/575479/bash-history-truncated-to-500-lines-on-each-login
export HISTFILE=~/.bash_eternal_history
# Force prompt to write history after every command.
# http://superuser.com/questions/20900/bash-history-loss
PROMPT_COMMAND="history -a; $PROMPT_COMMAND"

Uwaga: każde polecenie jest zapisywane natychmiast po uruchomieniu, więc jeśli przypadkowo wkleisz hasło, nie możesz po prostu „zabić -9 %%”, aby uniknąć zapisu historii, musisz usunąć je ręcznie.

Pamiętaj również, że każda sesja bash załaduje pełny plik historii do pamięci, ale nawet jeśli Twój plik historii powiększy się do 10 MB (co zajmie dużo czasu), nie zauważysz dużego wpływu na czas uruchamiania basha.

fotinakis
źródło
4
Plik historii jest obcinany po ustawieniu HISTFILESIZE, dlatego powinieneś usunąć każde zdarzenie takiego zdarzenia oprócz tego, którego chcesz. Zostanie również obcięty przy wyjściu z powłoki (ale jest to oczekiwane). I nie powinieneś potrzebować export.
vaab
3
@vaab Jeśli nie eksportujesz, zrobienie czegoś takiego bash --norcspowoduje ponowne obcięcie historii.
Yongwei Wu
1
Używam export HISTFILE="/home/$USER/hist/`uname -n``tty | tr '/' '-'`"do oddzielania historii powłoki osobno dla każdej sesji (na podstawie nazwy hosta i nazwy tty). Oczywiście najpierw muszę utworzyć katalog ~ / hist.
Jeff Learman
2
Pamiętaj, że możesz sprawdzić wartość PROMPT_COMMAND i nie ślepo dołączać tego wielokrotnie, ponieważ spowoduje to szalone rzeczy w twoim systemie. Sprawdzanie wartości zerowej lub jeszcze lepiej wyszukiwanie rozszerzenia zmiennej powłoki jest prawdopodobnie bezpieczniejsze.
dragon788
3
Używam tego, aby uniknąć problemu @ dragon788, o którym mowa:PROMPT_COMMAND="${PROMPT_COMMAND:+${PROMPT_COMMAND} ;}history -a";
Brian Vandenberg,
9

Uwzględnij w ~ / .bashrc :

# append a session's history on shell exit
shopt -s histappend
export HISTFILESIZE=
export HISTSIZE=

Ta odpowiedź spełnia następujące kryteria:

  1. osobna historia główna (żadna sesja nie może przerwać twojej historii)

  2. automatyczne zapisywanie historii (bez skrótów klawiszowych)

  3. rzadkie zapisy (brak dołączania po każdym poleceniu)

tło

Przy uruchamianiu interaktywnym, jeśli $HISTFILESIZEjest ustawiony na liczbę, bash obcina $HISTFILEten numer. Po zamknięciu interaktywnym, jeśli histappendustawiona jest opcja powłoki , bash dodaje $HISTSIZElinie do $HISTFILE, w przeciwnym razie nadpisuje $HISTFILE.

wskazówki dla OSX (Terminal)

Za każdym razem, gdy tworzona jest karta w Terminalu, ~/.bash_profilejest czytana, co oznacza, że ​​bash nie czyta dalej ~/.bashrc. Dodaj następujący wiersz do ~/etc/bash_profile:

# if bashrc has content, source it
[[ -s ~/.bashrc ]] && . ~/.bashrc

wskazówki dotyczące ekranu

Jeśli używasz screena, twój plik konfiguracyjny to ~ / .screenrc. Jeśli chcesz, aby ekran zapisywał historię, wystarczy ustawić go tak, aby używał powłoki logowania, która będzie pobierała pliki startowe bash (i zapisywała Twoją historię).

# use bash, make it a login shell
defshell -bash
cdosborn
źródło
3

Inna koncepcja (może nie mieć zastosowania), ale możesz mieć unlimitedhistorię, gdy używasz sink-shell .

ChristopheD
źródło