Konsekwentnie mam więcej niż jeden otwarty terminal. Gdziekolwiek od dwóch do dziesięciu, robiąc różne bity i boby. Powiedzmy teraz, że uruchamiam ponownie i otwieram inny zestaw terminali. Niektórzy pamiętają pewne rzeczy, inni zapominają.
Chcę historii, która:
- Zapamiętuje wszystko z każdego terminala
- Jest natychmiast dostępny z każdego terminala (np. Jeśli jestem
ls
w jednym, przełącz się na inny już działający terminal, a następnie naciśnij przycisk w górę,ls
pokazuje się) - Nie zapomina polecenia, jeśli z przodu polecenia są spacje.
Co mogę zrobić, aby bash działał w ten sposób?
export PROMPT_COMMAND="history -a; $PROMPT_COMMAND"
. Istniejące powłoki dodadzą każde polecenie do pliku historii, aby nowe powłoki mogły je zobaczyć, ale pokażą tylko własne historie.Odpowiedzi:
Dodaj następujące elementy do ~ / .bashrc
źródło
history -a
(...) nie powoduje kasowania duplikatów zgodnie z tym odpowiedź na pytanie historii Bash „ignoredups” i „erasedups” Ustawianie konflikt ze wspólnej historii całej sesji . Ta odpowiedź podaje również sekwencjęhistory -<option>
poleceń, która działa zHISTCONTROL=ignoredups:erasedups
ustawieniami.export
sięHISTCONTROL
iPROMPT_COMMAND
zmiennych: definiowania ich w.bashrc
tak zostaną one zdefiniowane w każdej muszli (nawet w tych nieinterakcyjnych, który jest również marnotrawstwem).To wszystko, co dotyczy historii
.bashrc
:Testowane w wersji bash 3.2.17 na Mac OS X 10.5, bash 4.1.7 na 10.6.
źródło
sleep 9999
i (nie czekając na zakończenie snu) w oknie powłoki B chcę widziećsleep 9999
historię bash.href
który odświeża historię mojego bieżącego terminala i czyści plik historii w tym procesie. Ilekroć otwieram nowy terminal, czyszczenie / synchronizacja jest wykonywana w moim pliku bashrc, więc nowy terminal ma najnowszą historię. Używam tego wraz zhistory -a
export
Zmienne nie mają powodu : definiujesz je,.bashrc
więc będą zdefiniowane w każdej powłoce (nawet w nieinteraktywnych, co również jest marnotrawstwem)Oto moja próba udostępniania historii sesji Bash. Umożliwi to dzielenie się historią między sesjami bash w taki sposób, że licznik historii nie zostanie pomieszany, a ekspansja historii jak
!number
będzie działać (z pewnymi ograniczeniami).Korzystanie z wersji Bash 4.1.5 pod Ubuntu 10.04 LTS (Lucid Lynx).
Wyjaśnienie:
Dołącz właśnie wprowadzoną linię do
$HISTFILE
(domyślnie jest.bash_history
). Spowoduje to$HISTFILE
wzrost o jedną linię.Ustawienie zmiennej specjalnej
$HISTFILESIZE
na pewną wartość spowoduje, że Bash$HISTFILE
nie będzie dłużej niż$HISTFILESIZE
linie, usuwając najstarsze wpisy.Wyczyść historię uruchomionej sesji. Spowoduje to zmniejszenie licznika historii o kwotę
$HISTSIZE
.Przeczytaj zawartość
$HISTFILE
i włóż je do bieżącej historii uruchomionych sesji. podniesie to licznik historii o liczbę linii w$HISTFILE
. Zauważ, że liczba wierszy$HISTFILE
niekoniecznie$HISTFILESIZE
.history()
Funkcja nadpisuje wbudowane historia, aby upewnić się, że historia jest zsynchronizowany zanim zostanie wyświetlona. Jest to konieczne do rozszerzenia historii według liczb (więcej na ten temat później).Więcej wyjaśnień:
Krok 1 zapewnia, że polecenie z bieżącej uruchomionej sesji zostanie zapisane w pliku historii globalnej.
Krok 4 zapewnia, że polecenia z innych sesji zostaną wczytane do bieżącej historii sesji.
Ponieważ krok 4 podniesie licznik historii, musimy w jakiś sposób zmniejszyć licznik. Odbywa się to w kroku 3.
W kroku 3 licznik historii jest zmniejszany o
$HISTSIZE
. W kroku 4 licznik historii jest podnoszony o liczbę linii w$HISTFILE
. W kroku 2 upewniamy się, że liczba wierszy$HISTFILE
jest dokładnie$HISTSIZE
(to znaczy, że$HISTFILESIZE
musi być taka sama jak$HISTSIZE
).O ograniczeniach ekspansji historii:
Korzystając z rozszerzania historii według numeru, należy zawsze wyszukać numer bezpośrednio przed użyciem. Oznacza to, że nie trzeba wyświetlać monitu między wyszukiwaniem numeru a jego użyciem. Zazwyczaj oznacza to brak Enter i brak ctrl + c.
Zasadniczo, gdy masz więcej niż jedną sesję Bash, nie ma żadnej gwarancji, że rozwinięcie historii według liczby zachowa swoją wartość między dwoma ekranami zachęty Bash. Ponieważ kiedy
PROMPT_COMMAND
jest wykonywana, historia wszystkich innych sesji Bash jest zintegrowana z historią bieżącej sesji. Jeśli jakakolwiek inna sesja bash ma nowe polecenie, numery historii bieżącej sesji będą inne.Uważam to ograniczenie za uzasadnione. I tak muszę za każdym razem sprawdzać liczbę, ponieważ nie pamiętam dowolnych liczb historycznych.
Zwykle używam rozszerzenia historii według liczb w ten sposób
Polecam użycie następujących opcji Bash.
Dziwne błędy:
Uruchomienie polecenia historii potokowanej do czegokolwiek spowoduje dwukrotne wyświetlenie tego polecenia w historii. Na przykład:
Wszystkie zostaną wyświetlone w historii dwukrotnie. Nie mam pojęcia dlaczego.
Pomysły na ulepszenia:
Zmodyfikuj funkcję,
_bash_history_sync()
aby nie działała za każdym razem. Na przykład nie powinien zostać wykonany poCTRL+C
znaku zachęty. Często używamCTRL+C
do odrzucenia długiej linii poleceń, gdy decyduję, że nie chcę jej wykonywać. Czasami muszę użyć,CTRL+C
aby zatrzymać skrypt zakończenia Bash.Polecenia z bieżącej sesji powinny zawsze być najnowszymi w historii bieżącej sesji. Spowoduje to również efekt uboczny, że dany numer historii zachowuje swoją wartość dla wpisów historii z tej sesji.
źródło
history -n
ponieważ to popsuło licznik historii. Ponadto okazałohistory -n
się , że jestem zbyt zawodny.history -a
bez-c
i-r
jest lepsze pod względem użyteczności (choć nie jest to pytanie zadawane). Oznacza to, że uruchamiane polecenia są dostępne natychmiast w nowych powłokach, nawet przed wyjściem z bieżącej powłoki, ale nie w równoległych uruchomionych powłokach. W ten sposób Arrow-Up wciąż wybiera ostatnie polecenia z bieżącej sesji , co wydaje mi się mniej skomplikowane.Nie znam żadnego sposobu używania
bash
. Ale to jedna z najpopularniejszych funkcjizsh
.Osobiście wolę
zsh
ponad,bash
więc polecam spróbować.Oto część mojej,
.zshrc
która dotyczy historii:źródło
Aby to zrobić, musisz dodać dwa wiersze do
~/.bashrc
:Od
man bash
:źródło
Możesz edytować monit BASH, aby uruchomić „history -a” i „history -r”, które zaproponował Muerr:
(na wypadek, gdybyś coś popsuł, co jest prawie gwarantowane)
(zwróć uwagę, że są to tyknięcia wstecz; będą one uruchamiać historię -a i historię -r dla każdego monitu. Ponieważ nie wypisują żadnego tekstu, twoje monity pozostaną niezmienione.
Po skonfigurowaniu zmiennej PS1 tak, jak chcesz, ustaw ją na stałe w pliku ~ / .bashrc.
Jeśli chcesz wrócić do pierwotnego monitu podczas testowania, wykonaj:
Przeprowadziłem podstawowe testy tego, aby upewnić się, że to działa, ale nie mogę rozmawiać z żadnymi efektami ubocznymi, które pojawiają się
history -a;history -r
przy każdym pytaniu.źródło
Jeśli potrzebujesz rozwiązania do synchronizacji historii bash lub zsh, które również rozwiązuje problem poniżej, zobacz go na stronie http://ptspts.blogspot.com/2011/03/how-to-automatically-synchronize-shell.html
Problem jest następujący: Mam dwa okna powłoki A i B. W oknie powłoki A uruchamiam
sleep 9999
i (bez oczekiwania na zakończenie snu) w oknie powłoki B chcę widziećsleep 9999
historię bash.Powodem, dla którego większość innych rozwiązań tutaj nie rozwiązuje tego problemu, jest to, że zapisują zmiany historii w pliku historii przy użyciu
PROMPT_COMMAND
lubPS1
oba z nich są wykonywane zbyt późno, dopiero po zakończeniusleep 9999
polecenia.źródło
Możesz użyć,
history -a
aby dołączyć historię bieżącej sesji do pliku histogramu, a następnie użyćhistory -r
na innych terminalach, aby odczytać plik histogramu.źródło
Tak, w końcu denerwowało mnie to, że znalazłem dobre rozwiązanie:
To coś w rodzaju połączenia tego, co zostało powiedziane w tym wątku, z tym wyjątkiem, że nie rozumiem, dlaczego po każdym poleceniu miałbyś przeładowywać historię globalną. Bardzo rzadko dbam o to, co dzieje się w innych terminalach, ale zawsze uruchamiam serię poleceń, powiedzmy w jednym terminalu:
(Uproszczony przykład)
A w innym:
Nie ma mowy, żebym chciał udostępnić polecenie
źródło
Oto alternatywa, której używam. Jest to uciążliwe, ale rozwiązuje problem, o którym wspominał @axel_c, w którym czasami możesz chcieć mieć osobne wystąpienie historii w każdym terminalu (jeden dla make, jeden dla monitorowania, jeden dla vima itp.).
Trzymam osobny dołączony plik historii, który stale aktualizuję. Mam następujące mapowanie na skrót:
Spowoduje to dołączenie całej historii z bieżącego terminala do pliku o nazwie master_history.txt w katalogu domowym.
Mam również osobny skrót do przeszukiwania głównego pliku historii:
Używam cat | grep, ponieważ pozostawia kursor na końcu, aby wprowadzić moje wyrażenie regularne. Mniej brzydkim sposobem na to byłoby dodanie kilku skryptów do ścieżki, aby wykonać te zadania, ale skróty klawiszowe działają dla moich celów. Od czasu do czasu ściągam historię z innych hostów, nad którymi pracowałem, i dołączam tę historię do mojego pliku master_history.txt.
Zawsze miło jest móc szybko wyszukać i znaleźć ten trudny regex, którego użyłeś lub ten dziwny perlowy liniowiec, który wymyśliłeś 7 miesięcy temu.
źródło
Mogę zaoferować poprawkę dla tego ostatniego: upewnij się, że zmienna env HISTCONTROL nie określa „ignorespace” (lub „ignoreboth”).
Ale odczuwam twój ból podczas wielu jednoczesnych sesji. Po prostu nie radzi sobie dobrze w bash.
źródło
Oto moja rozszerzeniem @ lesmana za odpowiedź . Główną różnicą jest to, że współbieżne okna nie współużytkują historii. Oznacza to, że możesz dalej pracować w swoich oknach, bez konieczności ładowania kontekstu z innych okien do twoich bieżących okien.
Jeśli jednoznacznie wpiszesz „historia”, LUB jeśli otworzysz nowe okno, otrzymasz historię ze wszystkich poprzednich okien.
Ponadto używam tej strategii do archiwizowania każdego polecenia wpisanego kiedykolwiek na moim komputerze.
źródło
Zdecydowałem się umieścić historię w pliku na plik, ponieważ wiele osób może pracować na tym samym serwerze - oddzielenie poleceń każdej sesji ułatwia audyt.
Historia wygląda teraz następująco:
Pliki wyglądają następująco:
źródło
Wskażę tutaj jeden problem
i
Jeśli uruchomisz source ~ / .bashrc, $ PROMPT_COMMAND będzie podobny
i
Powtórzenie to występuje przy każdym uruchomieniu „source ~ / .bashrc”. Możesz sprawdzić PROMPT_COMMAND po każdym uruchomieniu „source ~ / .bashrc”, uruchamiając „echo $ PROMPT_COMMAND”.
Widać, że niektóre polecenia są najwyraźniej zepsute: „history -n history -a”. Ale dobrą wiadomością jest to, że nadal działa, ponieważ inne części nadal tworzą prawidłową sekwencję poleceń (po prostu wiąże się to z dodatkowymi kosztami z powodu powtarzalnego wykonywania niektórych poleceń. I nie jest tak czyste).
Osobiście korzystam z następującej prostej wersji:
który ma większość funkcji, a nie ma takiego problemu jak wspomniano powyżej.
Kolejną kwestią do zrobienia jest: naprawdę nie ma magii . PROMPT_COMMAND to zwykła zmienna środowiskowa bash. Polecenia w nim wykonywane są wykonywane przed wyświetleniem monitu bash (znak $). Na przykład twój PROMPT_COMMAND to „echo 123”, a ty uruchamiasz „ls” w swoim terminalu. Efekt jest podobny do uruchomienia „ls; echo 123”.
wyjście (Podobnie jak uruchomienie „PROMPT_COMMAND =„ echo 123 ”; $ PROMPT_COMMAND”):
Uruchom następujące czynności:
wynik:
„history -a” służy do zapisywania poleceń historii w pamięci do ~ / .bash_history
„history -c” służy do usuwania poleceń historii z pamięci
„history -r” służy do odczytu poleceń historii z ~ / .bash_history do pamięci
Zobacz wyjaśnienie polecenia historii tutaj: http://ss64.com/bash/history.html
PS: Jak zauważyli inni użytkownicy, eksport nie jest konieczny. Zobacz: za pomocą eksportu w .bashrc
źródło
Napisałem skrypt do ustawiania pliku historii na sesję lub zadania w oparciu o następujące.
Nie trzeba zapisywać każdego polecenia historii, ale zapisuje te, na których mi zależy, i łatwiej je odzyskać niż wykonać każde polecenie. Moja wersja zawiera także listę wszystkich plików historii i umożliwia przeszukiwanie ich wszystkich.
Pełne źródło: https://github.com/simotek/scripts-config/blob/master/hiset.sh
źródło
Oto rozwiązanie, które nie miesza historii z poszczególnych sesji!
Zasadniczo należy przechowywać historię każdej sesji osobno i odtwarzać ją przy każdym monicie. Tak, zużywa więcej zasobów, ale nie jest tak powolny, jak może się wydawać - opóźnienie zaczyna być zauważalne tylko, jeśli masz więcej niż 100000 wpisów historii.
Oto podstawowa logika:
Zobacz tę listę, aby uzyskać pełne rozwiązanie, w tym niektóre zabezpieczenia i optymalizacje wydajności.
źródło
Działa to dla ZSH
źródło
Od dawna chciałem tego, zwłaszcza możliwości pobrania polecenia według miejsca, w którym zostało uruchomione w celu ponownego uruchomienia w nowym projekcie (lub znalezienia katalogu za pomocą polecenia). Więc zestawiłem to narzędzie , które łączy poprzednie rozwiązania do przechowywania globalnej historii CLI z interaktywnym narzędziem grepping o nazwie percol (mapowane na C ^ R). Nadal jest zręczny na pierwszej maszynie, z której zacząłem go używać, teraz z ponad 2-letnią historią CLI.
Nie bałagan z lokalną historią CLI, jeśli chodzi o klawisze strzałek, ale pozwala dość łatwo uzyskać dostęp do historii globalnej (którą można również odwzorować na coś innego niż C ^ R)
źródło
Ponieważ wolę nieskończoną historię zapisaną w pliku niestandardowym. Tworzę tę konfigurację na podstawie https://stackoverflow.com/a/19533853/4632019 :
źródło
Oto fragment mojego pliku .bashrc i krótkie objaśnienia, gdy są potrzebne:
HISTFILESIZE i HISTSIZE są osobistymi preferencjami i możesz je zmieniać według własnych upodobań.
źródło