Obsługa historii bashów z wieloma terminalami

110

Używam głównie Terminatora i zwykle jest on otwierany za pomocą 3 podzielonych okien terminali. Używam również terminala Gnome z różnych powodów.
Zastanawiam się, jak w tym przypadku obsługiwana jest historia bash, ponieważ czasami brakuje mi wcześniej wydanych poleceń podczas uruchamianiahistory

Na przykład mój monit wyświetla bieżącą linię historii bash ( \!) i jeśli uruchomię Terminator z 3 podzielonymi oknami terminala, otrzymam tę samą linię historii (powiedzmy 100) na wszystkich terminalach. Która historia zostanie zapisana?

Również uruchamiając Gnome Terminal po użyciu Terminatora, dostaję linię 100 przy uruchomieniu, niezależnie od wszystkich poleceń wydanych wcześniej w Terminatorze

zetah
źródło
Powiązane z Unix SE: Zachowaj historię bash w wielu oknach terminalu
Marc.2377

Odpowiedzi:

107

Zapisana sesja bash jest sesją dla terminala, który jest zamknięty najpóźniej. Jeśli chcesz zapisać polecenia dla każdej sesji, możesz skorzystać ze sztuczki opisanej tutaj .

export PROMPT_COMMAND='history -a'

Cytując stronę podręcznika: „Jeśli jest ustawiona, wartość jest wykonywana jako polecenie przed wydaniem każdego głównego monitu.”

Tak więc za każdym razem, gdy moje polecenie kończy się, dołącza niepisany element historii ~/.bash_historyprzed ponownym wyświetleniem monitu (tylko $ PS1).

Więc po wprowadzeniu tej linii /etc/bash.bashrcnie muszę odkrywać na nowo kół ani tracić cennych sekund na ponownym pisaniu, tylko dlatego, że byłem leniwy z terminalami.

W każdym razie musisz wziąć pod uwagę, że polecenia z różnych sesji będą mieszane w twoim pliku historii, więc później nie będzie tak łatwo je przeczytać.

Zobacz też:

jcollado
źródło
czy nie jest przechowywane osobno dla różnych TTL?
Vineet Menon,
Doskonały. Dzięki za wyjaśnienie i rozwiązanie. Próbowałem z export PROMPT_COMMAND='history -a; history -r'i otrzymałem kilka dziwnych numerów linii historii w terminalu - po wydaniu niektórych numerów linii historii poleceń przeskakuje o 2000 zamiast o 1, co jest dziwne, ale zachowuje się tak, jak powiedziano - cała historia terminali zostaje zapisana.
zetah
@VineetMenon Aby uzyskać więcej informacji, spójrz tutaj . Interesujące części: Gdy powłoka się uruchamia, historia jest inicjowana z pliku o nazwie zmiennej HISTFILE (domyślnie `~ / .bash_history '). [...] Po wyjściu powłoki interaktywnej ostatnie linie $ HISTSIZE są kopiowane z listy historii do pliku o nazwie $ HISTFILE.
jcollado,
Wygląda na to, że ta strona internetowa nie
działa
32

Po wielu odczytach man bashużywam osobnych plików historii dla każdej powłoki. Zrobiłem mkdir -m 0700 ~/.historywtedy dodane

[[ -d ~/.history ]] || mkdir --mode=0700 ~/.history
[[ -d ~/.history ]] && chmod 0700 ~/.history
HISTFILE=~/.history/history.$(date +%y%b%d-%H%M%S).$$
# close any old history file by zeroing HISTFILESIZE  
HISTFILESIZE=0  
# then set HISTFILESIZE to a large value
HISTFILESIZE=4096  
HISTSIZE=4096  

do mojego ~/.bashrc. Co jakiś czas pamiętam du -sk .historyi czyściłem to. Miło jest zachować dla mnie każde wpisane polecenie.

Po prostu użyłem powyższego, aby zobaczyć, co ostatnio robiłem:
cut -f1 "-d " .history/* | sort | uniq -c |sort -n -r |less
lub
cut -f1-2 "-d " .history/* | sort | uniq -c |sort -n -r |less
(aby uwzględnić pierwszy argument, np. sudo mountW łańcuchu sortowania).

waltinator
źródło
3
Dlaczego przypisujesz HISTFILESIZEdwa razy?
Daniel
2
Ustawiając HISTFILESIZE na 0, usuwam bufor historii i resetuję mechanizm zapisywania historii. Następnie ustawiam rozmiar, który naprawdę chcę, i zaczynam zapisywać historię w HISTFILE. Zobacz sekcję HISTORIA man bash.
waltinator,
1
czy istnieje sposób na scalenie plików historii w celu Ctrl+rponownego uruchomienia ?
n611x007
3
To powinno być nowe pytanie, ale nie sądzę, że to dobry pomysł. Zamiast tego używam egrep 'whatever' .history/*(lub cat .history/* | egrep 'whatever') i Ctrl-r do przeszukiwania historii poszczególnych sesji. Przeczytaj man bash-builtinso poleceniu historii. Moje sort .history/* | uniq -c | sort -n | wc -lpokazuje 16033 unikalne polecenia, cut '-d ' -f1 .history/* | sort | uniq -c | sort -npokazuje 2004 unikalne polecenia, głównie literówki. Załadowanie tego wszystkiego na „listę historii” basha nie pomogłoby.
waltinator
@waltinator - wiem, że to stary komentarz, ale czy sugerujesz, że ustawienie zmiennej środowiskowej w jakiś sposób wyzwala natychmiastowe działanie? jaki proces wykryje fakt, że przypisałeś wartość 0 HISTFILESIZE w lokalnej powłoce, a następnie natychmiast zmienisz na 4096? czy jest to coś nieudokumentowanego w obsłudze niektórych nazw zmiennych przez bash?
niezsynchronizowany
8

Aby wyświetlić historyze wszystkich terminali:

Dodaj export PROMPT_COMMAND='history -a; history -r'do pliku .bashrc.

Źródło: http://northernmost.org/blog/flush-bash_history-after-each-command


Elijah Lynn
źródło
3
Powiem, że po kilku miesiącach używania tego skomentowałem to niedawno. Jest słodko-gorzki, ponieważ nie zawsze chcę przesiewać ostatnie 100 poleceń, aby uruchomić to, które pierwotnie uruchomiłem w okienku Tmux. Czasami mogę mieć dedykowane polecenie dziennika, w którym muszę zrestartować.
Elijah Lynn
Ładne rozwiązanie, które oferuje skorupa ryb to history --merge. Używam tego od około roku i to rozwiązuje problem. Kiedy chcę najnowszej historii z innych sesji, po prostu uruchamiam to polecenie i jest ono od razu dostępne.
Elijah Lynn
eksport nie jest potrzebny.
Ograniczone Zadośćuczynienie
6

Zobacz także „ utrzymywanie trwałej historii w bash ”, aby zobaczyć inną alternatywę. Podpisuje monit o wysłanie wszystkich poleceń wpisanych do dowolnego terminala do pliku „trwałej historii” (wraz z tym, co zwykle robi się dla zwykłego .history).

Eli Bendersky
źródło
1
Wstawiłem $$, aby utworzyć linię echo $$ $date_part "$command_part" >> ~/.persistent_historyTo poprzedza wpisy PID ich procesu bash, abyśmy mogli rozplątać wiele historii.
Evgeni Sergeevev
Czy alternatywną historię można wykorzystać do wyszukiwania historii CTRL-R?
maks.