Збережіть історію bash у кількох вікнах терміналів


526

У мене постійно відкрито більше одного терміналу. Десь від двох до десяти, роблячи різні біти та боби. Скажімо, я перезапускаю і відкриваю інший набір терміналів. Деякі пам'ятають певні речі, деякі забувають.

Я хочу історію, яка:

  • Згадує все з кожного терміналу
  • Доступний миттєво з кожного терміналу (наприклад, якщо я lsв одному, перейдіть на інший вже запущений термінал, а потім натисніть, lsвідображається)
  • Не забуває команду, якщо в передній частині команди є пробіли.

Що я можу зробити, щоб зробити баш-роботу більш подібною?


57
Я бачу перевагу в цьому, але особисто я б ненавиджу це в своїй оболонці. Зазвичай я тримаю 3 або 4 вкладки відкритими в своєму терміналі для дуже конкретного використання: одна для запуску 'make', одна з vi, одна для запуску матеріалів тощо. Отже, коли я компілюю, переходжу до вкладки 1, натискаю і 'make' 'підходить тощо. Це надзвичайно продуктивно для мене. Тож якщо раптом я заходжу на вкладку "make" і натискаю, і з'являється якась випадкова команда grep, я б справді злий! Лише особиста записка
axel_c

4
@axel_c, це правда. Я не можу придумати розумний спосіб зробити це там, де існуючі термінали бачать лише свою історію, а нові бачать хронологічно точний список команд.
Олі

8
@Oli писав: "Я не можу придумати розумний спосіб зробити це там, де існуючі термінали бачать лише свою історію, а нові бачать хронологічно точний список команд". Як щодо (неперевірений): export PROMPT_COMMAND="history -a; $PROMPT_COMMAND". Існуючі оболонки додадуть кожну команду до файлу історії, щоб нові оболонки могли бачити, але лише показувати власні історії.
Кріс Пейдж

2
Ви хочете, щоб історія зберігалася окремо або всі були об'єднані в один файл історії?
kbyrd

3
Коротка відповідь: це не призначено розробниками bash. Рішення, засновані на промиванні, а потім перечитуванні історії, ймовірно, спрацьовують, але остерігайтеся Shlemiel The Painter . Простими словами: кількість обробних робіт між кожною командою пропорційна розміру історії.
Стефан Гурішон

Відповіді:


329

Додайте до ~ / .bashrc

# Avoid duplicates
export HISTCONTROL=ignoredups:erasedups  
# When the shell exits, append to the history file instead of overwriting it
shopt -s histappend

# After each command, append to the history file and reread it
export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"

20
Проблема з цим рішенням PROMPT_COMMAND полягає в тому, що цифри для кожного елемента історії змінюються після кожної команди :(. Наприклад, якщо ви вводите історію та 1) ls 2) rm, ви робите! 1, щоб повторити 1, номер історії може змінитися і може запустити команду rm ...
Кріс Кімптон

2
Коли я це роблю, інші вже відкриті термінали не мають останньої введеної команди, коли я натискаю "Вгору", поки не видаю команду в цьому терміналі - це очікується? Якщо так, чи існує спосіб по-справжньому змінити історію інших терміналів?
Суан

7
@Suan, мені здається, це правильно на основі команд. Я виявив, що ми можемо видати нульову команду (просто натисніть клавішу Enter), щоб отримати історію оновлення.
шавлія

3
Насправді history -a(...) не викликає стирання дублікатів відповідно до цієї відповіді на запитання " Історія башів": "ігнорування" та "стирання" налаштування конфліктують із загальною історією протягом сесій . Ця відповідь також дає послідовність history -<option>команд, яка працює з HISTCONTROL=ignoredups:erasedupsналаштуванням.
Пьотр Доброгост

23
Там немає ніяких підстав exportв HISTCONTROLі PROMPT_COMMANDзмінних: ви визначаєте їх , .bashrcтаким чином вони будуть визначені в кожній оболонці (навіть в не-інтерактивних, який також є марнотратним).
долмен

248

Отже, це все, що стосується моєї історії .bashrc:

export HISTCONTROL=ignoredups:erasedups  # no duplicate entries
export HISTSIZE=100000                   # big big history
export HISTFILESIZE=100000               # big big history
shopt -s histappend                      # append to history, don't overwrite it

# Save and reload the history after each command finishes
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Тестований на bash 3.2.17 на Mac OS X 10.5, bash 4.1.7 на 10.6.


3
Хм .. Це вбиває можливість використання $! 34, оскільки номери команд змінюють кожен запит. Чи існує спосіб вирішення @Davide @Schof @kch?

5
Використовуйте це, щоб отримати нескінченну історію . ЗАРАЗ, це безкоштовно для коду вище, оскільки він не буде завантажений автоматично.

7
FYI Жоден із згаданих тут рішень не може вирішити наступну проблему. У мене є два вікна оболонки A і B. У вікні A оболонки A я запускаюсь sleep 9999і (не чекаючи, коли сон закінчиться) у вікні B оболонки, я хочу мати змогу бачити sleep 9999історію баш.
пт

1
@pts Я теж мав на меті живу поведінку, але потім зрозумів, що зручніше мати конкретні історії, які полегшують роботу над різними речами в різних терміналах. Я вважаю це дуже корисним: stackoverflow.com/questions/338285/#answer-7449399 Виходячи з цього, я створив собі псевдонім, який називається, hrefщо оновлює історію мого поточного терміналу миттєво і очищає файл історії в процесі. Щоразу, коли я відкриваю новий термінал, це очищення / синхронізація виконується у моєму файлі bashrc, тому новий термінал має останню історію. Я використовую це разом ізhistory -a
trusktr

6
Немає жодних причин для exportзмінних: ви визначаєте їх, .bashrcщоб вони були визначені в кожній оболонці (навіть у неінтерактивних, що також є марнотратним)
dolmen

118

Ось моя спроба обміну історією сеансів Bash. Це дозволить обмінюватися історією між bash-сесіями таким чином, щоб лічильник історії не змішувався, а розширення історії як би !numberпрацювало (з деякими обмеженнями).

Використання Bash версії 4.1.5 під Ubuntu 10.04 LTS (Lucid Lynx).

HISTSIZE=9000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups

_bash_history_sync() {
    builtin history -a         #1
    HISTFILESIZE=$HISTSIZE     #2
    builtin history -c         #3
    builtin history -r         #4
}

history() {                  #5
    _bash_history_sync
    builtin history "$@"
}

PROMPT_COMMAND=_bash_history_sync

Пояснення:

  1. Додайте щойно введений рядок до $HISTFILE(за замовчуванням є .bash_history). Це призведе $HISTFILEдо росту на одну лінію.

  2. Якщо встановити спеціальну змінну $HISTFILESIZEна якесь значення, це призведе до того, що Bash для усікання $HISTFILEбуде не більше $HISTFILESIZEрядків, видаляючи найдавніші записи.

  3. Очистіть історію запущеного сеансу. Це зменшить лічильник історії на суму $HISTSIZE.

  4. Прочитайте вміст $HISTFILEта вставте їх у поточну історію запущених сесій. це підніме лічильник історії на кількість рядків у $HISTFILE. Зауважте, що кількість рядків $HISTFILEне обов'язково $HISTFILESIZE.

  5. history()Функція скасовує вбудована історію , щоб переконатися , що історія синхронізується перед його відображенням. Це необхідно для розширення історії за кількістю (докладніше про це пізніше).

Більше пояснення:

  • Крок 1 гарантує, що команда з поточного запущеного сеансу записується у файл глобальної історії.

  • Крок 4 гарантує, що команди з інших сесій будуть прочитані в поточну історію сеансів.

  • Оскільки крок 4 підніме лічильник історії, нам потрібно дещо зменшити лічильник. Це робиться на кроці 3.

  • На кроці 3 лічильник історії зменшується на $HISTSIZE. На кроці 4 лічильник історії піднімається на кількість рядків у $HISTFILE. На кроці 2 ми переконуємося, що кількість рядків $HISTFILEточно така $HISTSIZE(це означає, що вона $HISTFILESIZEповинна бути такою ж, як $HISTSIZE).

Про обмеження розширення історії:

Використовуючи розширення історії за номером, завжди слід шукати номер безпосередньо перед його використанням. Це означає, що немає пошуку швидкого відображення між пошуком номера та його використанням. Це, як правило, означає, що не вводиться і немає ctrl + c.

Як правило, після того, як у вас буде більше одного сеансу Bash, жодної гарантії не буде, що розширення історії за кількістю збереже своє значення між двома дисплеями підказки Bash. Тому що, коли PROMPT_COMMANDвиконується, історія всіх інших сесій Bash інтегрується в історію поточного сеансу. Якщо будь-який інший сеанс bash має нову команду, то номери історії поточного сеансу будуть різними.

Я вважаю це обмеження розумним. Я мушу шукати це число кожного разу, тому що не можу згадати довільні номери історії.

Зазвичай я використовую розширення історії за таким числом

$ history | grep something #note number
$ !number

Я рекомендую використовувати наступні варіанти Bash.

## reedit a history substitution line if it failed
shopt -s histreedit
## edit a recalled history line before executing
shopt -s histverify

Дивні помилки:

Якщо запустити команду "Історія", що передається на будь-що, призведе до того, що команда буде вказана в історії двічі. Наприклад:

$ history | head
$ history | tail
$ history | grep foo
$ history | true
$ history | false

Усі будуть перераховані в історії двічі. Я поняття не маю, чому.

Ідеї ​​покращення:

  • Змініть функцію, _bash_history_sync()щоб вона не виконувалась кожного разу. Наприклад, він не повинен виконуватись після CTRL+Cпідказки a . Я часто використовую, CTRL+Cщоб відкинути довгий командний рядок, коли вирішую, що не хочу виконувати цей рядок. Іноді мені доводиться використовувати CTRL+Cдля зупинки сценарій завершення Bash.

  • Команди з поточного сеансу завжди повинні бути останніми в історії поточного сеансу. Це також матиме побічний ефект, що заданий номер історії зберігає своє значення для записів історії цього сеансу.


1
Чому б не "історія -n" (перезавантаження рядків ще не завантажено) замість "історія -c; історія -r"?
Грем

@Graham: Я не хотів використовувати, history -nтому що це переплутало лічильник історії. Також я виявив history -nсебе занадто ненадійним.
lesmana

1
Один недолік: Команди з рядковими рядками зазвичай зберігаються в поточному сеансі. За допомогою цього фокусу вони розбиваються на окремі рядки миттєво. Використання -n для -c -r не допомагає, ні cmdhist, ні літист. Я не думаю, що тут є рішення.
Джо Лісс

24
Спробувавши це трохи, я фактично виявив, що біг тільки history -a, без -cі -r, є кращим для зручності використання (хоча це не те, про що задається питання). Це означає, що команди, які ви запускаєте, доступні миттєво в нових оболонках навіть перед виходом із поточної оболонки, але не в одночасно запущених оболонках. Таким чином, Arrow-Up все ще вибирає команди останнього запуску поточного сеансу , які я вважаю набагато менш заплутаними.
Жо Лісс

надзвичайно гарна відповідь, це працює надійно на відміну від більш поширеного "історії -a; історія -n"
RichVel

42

Я не знаю про будь-який спосіб використання bash. Але це одна з найпопулярніших особливостей zsh.
Особисто я віддаю перевагу zshбільш , bashтому я рекомендую спробувати його.

Ось частина мого, .zshrcщо стосується історії:

SAVEHIST=10000 # Number of entries
HISTSIZE=10000
HISTFILE=~/.zsh/history # File
setopt APPEND_HISTORY # Don't erase history
setopt EXTENDED_HISTORY # Add additional data to history like timestamp
setopt INC_APPEND_HISTORY # Add immediately
setopt HIST_FIND_NO_DUPS # Don't show duplicates in search
setopt HIST_IGNORE_SPACE # Don't preserve spaces. You may want to turn it off
setopt NO_HIST_BEEP # Don't beep
setopt SHARE_HISTORY # Share history between session/terminals


16

Для цього вам потрібно додати два рядки до своїх ~/.bashrc:

shopt -s histappend
PROMPT_COMMAND="history -a;history -c;history -r;$PROMPT_COMMAND"

Від man bash:

Якщо параметр оболонки histappend увімкнено (див. Опис простріленого під SHELL BUILTIN COMMANDS нижче), рядки додаються до файлу історії, інакше файл історії перезаписаний.


10

Ви можете відредагувати підказку BASH, щоб запустити "історію -а" та "історію -р", яку запропонував Muerr:

savePS1=$PS1

(якщо ви щось зіпсуєте, що майже гарантовано)

PS1=$savePS1`history -a;history -r`

(зауважте, що це зворотні кліти; вони будуть виконувати історію -a та історію -r у кожному запиті. Оскільки вони не виводять жодного тексту, ваше запит буде незмінним.

Після встановлення змінної PS1 так, як вам потрібно, встановіть її назавжди у вашому файлі ~ / .bashrc.

Якщо ви хочете повернутися до оригінального підказки під час тестування, зробіть:

PS1=$savePS1

Я провів базове тестування на цьому, щоб переконатися, що він працює, але не може говорити про будь-які побічні ефекти від запуску history -a;history -rкожного запиту.


2
Рішення kch працює краще, ніж у мене. Зараз я використовую його рішення в моєму .bashrc.

9

Якщо вам потрібне рішення для синхронізації історії bash або zsh, яке також вирішує проблему нижче, перегляньте це за адресою http://ptspts.blogspot.com/2011/03/how-to-automatically-synchronize-shell.html

Проблема полягає в наступному: у мене є два вікна оболонки A і B. У вікні A оболонки A я запускаюсь sleep 9999(і не чекаючи, коли сон закінчиться) у вікні B оболонки, я хочу мати змогу побачити sleep 9999історію башів.

Причина, чому більшість інших рішень тут не вирішить цю проблему, полягає в тому, що вони записують свої зміни в історію, використовуючи файл, PROMPT_COMMANDабо PS1обидва вони виконуються занадто пізно, лише після того, як sleep 9999команда закінчиться.


1
Це приємне рішення, але у мене все-таки є кілька питань. 1. Чи можу я використовувати оригінальний файл .bash_history, я не хочу, щоб ще один файл історії башів існував у моєму $ HOME 2. Можливо, вам слід розглянути можливість встановити для цього github repo.
weynhamz

Здається, гак налагодження конфліктує з bashdb, наступний вихід кожного разу, коли я запускаю сеанс bashdb. `` `bash debugger, bashdb, release 4.2-0.8 Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Rocky Bernstein Це вільне програмне забезпечення, на яке поширюється Загальна публічна ліцензія GNU, і ви можете змінити його та / або поширити його копії за певних умов. ** Внутрішня помилка налагодження _Dbg_is_file (): аргумент файлу null bash: _Dbg_filenames [$ fullname]: підпис підписного масиву `` `
weynhamz

@Techlive Zheng: 1. Оригінальний .bash_history навмисно не підтримується, тому що .merged_bash_history використовує інший формат файлу, тому у випадку .merged_bash_history не вдасться завантажити належним чином, bash не випадково заглушить накопичену історію. Міцність за конструкцією зберігатиметься як є. 2. Загалом github repo - це гарна ідея, але я не маю часу підтримувати це для цього проекту, тому я цього не роблю. - Так, це конфліктує з bashdb, і немає простого рішення (вони використовують ті самі гачки). Я не планую працювати над виправленням, але приймаю патчі.
пт

В порядку спасибі. Я придумав набагато простіший і кращий сумот.
weynhamz

@TechliveZheng: Чи поділилися б ви своїм простим і кращим рішенням, щоб ми всі могли з нього вчитися? (Якщо так, то будь-ласка, додайте відповідь на запитання.)
пт

8

Ви можете використовувати, history -aщоб додати історію поточного сеансу до історіфайлу, а потім скористатися history -rна інших терміналах, щоб прочитати історфіл. 


8

Правильно, тож нарешті це мене роздратувало знайти гідне рішення:

# Write history after each command
_bash_history_append() {
    builtin history -a
}
PROMPT_COMMAND="_bash_history_append; $PROMPT_COMMAND"

Що це робить, це свого роду об'єднання того, що було сказано в цій темі, за винятком того, що я не розумію, чому ви перезавантажуєте глобальну історію після кожної команди. Мені дуже рідко цікаво, що відбувається в інших терміналах, але я завжди виконую ряд команд, скажімо, в одному терміналі:

make
ls -lh target/*.foo
scp target/artifact.foo vm:~/

(Спрощений приклад)

А в іншому:

pv ~/test.data | nc vm:5000 >> output
less output
mv output output.backup1

Ні в якому разі не хотілося б, щоб команда була спільною


1
Причина, коли ви перезавантажуєте історію після кожної команди, полягає в тому, що це поведінка, яку вимагає запитання (і тому це насправді не відповідає на поставлене запитання).
Майкл Гомер

2
@MichaelHomer Справедливий пункт. Не соромтеся оскаржувати, так що відповідь залишається внизу, однак я б доміг цього до ОП, не усвідомлюючи, наскільки поганою буде запитувана поведінка, і той факт, що це дуже гучне питання.
Ярек Т

3
Оп, так, це справедливий компроміс. Моя головна скарга на те, що я втрачав історію. Це повинно зупинити це, навіть якщо це не означає миттєві оновлення протягом одночасних сеансів.
Олі

7

Ось альтернатива, яку я використовую. Це громіздко, але він вирішує проблему, яку @axel_c згадував, де іноді ви можете мати окремий екземпляр історії у кожному терміналі (один для make, один для моніторингу, один для vim тощо).

Я зберігаю окремий доданий файл історії, який я постійно оновлюю. На гарячу клавішу відображено наступне:

history | grep -v history >> ~/master_history.txt

Це додає всю історію з поточного терміналу до файлу під назвою master_history.txt у вашому домашньому режимі.

У мене також є окрема швидка клавіша для пошуку через головний файл історії:

cat /home/toby/master_history.txt | grep -i

Я використовую кішку | grep, тому що він залишає курсор наприкінці, щоб увійти до мого регексу. Менш некрасивим способом зробити це було б додати пару сценаріїв до вашого шляху для виконання цих завдань, але гарячі клавіші працюють для моїх цілей. Я також періодично витягуватиму історію з інших хостів, над якими я працював, і додаю цю історію до свого файлу master_history.txt.

Завжди приємно мати можливість швидко знайти і знайти той хитрий вираз, який ви використовували, або той дивний перламутровий перламутр, який ви придумали 7 місяців тому.


6

Я можу запропонувати виправлення для останнього: переконайтеся, що в змінній env HISTCONTROL не вказано "ignorespace" (або "ignoreboth").

Але я відчуваю твій біль при кількох одночасних сеансах. З ним просто не справляється добре.


6

Ось моє удосконалення @ lesmana в відповідь . Основна відмінність полягає в тому, що паралельні вікна не діляться історією. Це означає, що ви можете продовжувати працювати у своїх вікнах, не маючи контексту, коли інші вікна завантажуються у ваші поточні вікна.

Якщо ви явно вводите "історію", АБО якщо ви відкриєте нове вікно, ви отримаєте історію з усіх попередніх вікон.

Також я використовую цю стратегію для архівації кожної команди, коли-небудь набраної на моїй машині.

# Consistent and forever bash history
HISTSIZE=100000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups

_bash_history_sync() {
  builtin history -a         #1
  HISTFILESIZE=$HISTSIZE     #2
}

_bash_history_sync_and_reload() {
  builtin history -a         #1
  HISTFILESIZE=$HISTSIZE     #2
  builtin history -c         #3
  builtin history -r         #4
}

history() {                  #5
  _bash_history_sync_and_reload
  builtin history "$@"
}

export HISTTIMEFORMAT="%y/%m/%d %H:%M:%S   "
PROMPT_COMMAND='history 1 >> ${HOME}/.bash_eternal_history'
PROMPT_COMMAND=_bash_history_sync;$PROMPT_COMMAND

5

Я вирішив поставити історію у файл-на-ціл, оскільки на одному сервері можуть працювати декілька людей - розділення команд кожного сеансу полегшує аудит.

# Convert /dev/nnn/X or /dev/nnnX to "nnnX"
HISTSUFFIX=`tty | sed 's/\///g;s/^dev//g'`
# History file is now .bash_history_pts0
HISTFILE=".bash_history_$HISTSUFFIX"
HISTTIMEFORMAT="%y-%m-%d %H:%M:%S "
HISTCONTROL=ignoredups:ignorespace
shopt -s histappend
HISTSIZE=1000
HISTFILESIZE=5000

Зараз історія виглядає так:

user@host:~# test 123
user@host:~# test 5451
user@host:~# history
1  15-08-11 10:09:58 test 123
2  15-08-11 10:10:00 test 5451
3  15-08-11 10:10:02 history

Файли виглядають так:

user@host:~# ls -la .bash*
-rw------- 1 root root  4275 Aug 11 09:42 .bash_history_pts0
-rw------- 1 root root    75 Aug 11 09:49 .bash_history_pts1
-rw-r--r-- 1 root root  3120 Aug 11 10:09 .bashrc

3

Тут я зазначу одну проблему

export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"

і

PROMPT_COMMAND="$PROMPT_COMMAND;history -a; history -n"

Якщо ви запустите source ~ / .bashrc, $ PROMPT_COMMAND буде подібний

"history -a; history -c; history -r history -a; history -c; history -r"

і

"history -a; history -n history -a; history -n"

Це повторення відбувається кожного разу, коли ви запускаєте 'source ~ / .bashrc'. Ви можете перевірити PROMPT_COMMAND після кожного запуску "source ~ / .bashrc", запустивши "echo $ PROMPT_COMMAND".

Ви могли бачити, що деякі команди, мабуть, порушені: "історія -n історія -a". Але гарна новина полягає в тому, що вона все-таки працює, тому що інші частини все ще утворюють дійсну послідовність команд (Просто пов'язані з деякими додатковими витратами за рахунок повторного виконання деяких команд. І не дуже чисто).

Особисто я використовую таку просту версію:

shopt -s histappend
PROMPT_COMMAND="history -a; history -c; history -r"

який має більшість функціональних можливостей, але немає такого питання, як згадувалося вище.

Ще один момент, який слід зазначити: насправді немає нічого магічного . PROMPT_COMMAND - це просто звичайна змінна середовище bash. Команди в ньому виконуються перед тим, як отримати команду bash (знак $). Наприклад, ваш PROMPT_COMMAND - "echo 123", і ви запускаєте "ls" у своєму терміналі. Ефект на зразок запуску "ls; echo 123".

$ PROMPT_COMMAND="echo 123"

вихід (подібно до запуску 'PROMPT_COMMAND = "ехо 123"; $ PROMPT_COMMAND'):

123

Виконайте наступне:

$ echo 3

вихід:

3
123

"history -a" використовується для запису команд історії в пам'ять до ~ / .bash_history

"history -c" використовується для очищення команд історії в пам'яті

"історія -r" використовується для читання команд історії з ~ / .bash_history до пам'яті

Пояснення команд історії див. Тут: http://ss64.com/bash/history.html

PS: Як зазначали інші користувачі, експорт зайвий. Див.: Використання експорту в .bashrc


2

Я написав сценарій для встановлення файла історії на сеанс чи завдання, виходячи з наступного.

        # write existing history to the old file
        history -a

        # set new historyfile
        export HISTFILE="$1"
        export HISET=$1

        # touch the new file to make sure it exists
        touch $HISTFILE
        # load new history file
        history -r $HISTFILE

Не потрібно зберігати кожну команду історії, але вона зберігає ті, про які я хвилююсь, і простіше їх отримання, а потім проходження кожної команди. Моя версія також перераховує всі файли історії та надає можливість пошуку через них усі.

Повне джерело: https://github.com/simotek/scripts-config/blob/master/hiset.sh


2

Ось рішення, яке не змішує історії з окремих сеансів!

В основному потрібно зберігати історію кожного сеансу окремо і відтворювати її в кожному підказку. Так, він використовує більше ресурсів, але це не так повільно, як це може здатися - затримка починає бути помітною лише за наявності у вас понад 100000 записів історії.

Ось основна логіка:

# on every prompt, save new history to dedicated file and recreate full history
# by reading all files, always keeping history from current session on top.
update_history () {
  history -a ${HISTFILE}.$$
  history -c
  history -r
  for f in `ls ${HISTFILE}.[0-9]* | grep -v "${HISTFILE}.$$\$"`; do
    history -r $f
  done
  history -r "${HISTFILE}.$$"
}
export PROMPT_COMMAND='update_history'

# merge session history into main history file on bash exit
merge_session_history () {
  cat ${HISTFILE}.$$ >> $HISTFILE
  rm ${HISTFILE}.$$
}
trap merge_session_history EXIT

Дивіться цей суть для повного рішення, включаючи деякі гарантії та оптимізації роботи.


1

Це працює для ZSH

##############################################################################
# History Configuration for ZSH
##############################################################################
HISTSIZE=10000               #How many lines of history to keep in memory
HISTFILE=~/.zsh_history     #Where to save history to disk
SAVEHIST=10000               #Number of history entries to save to disk
#HISTDUP=erase               #Erase duplicates in the history file
setopt    appendhistory     #Append history to the history file (no overwriting)
setopt    sharehistory      #Share history across terminals
setopt    incappendhistory  #Immediately append to the history file, not just when a term is killed

на жаль, питання суто до
башу

1
це перший результат в Google, коли я шукаю також zsh ... Думав, що це може допомогти
Mulki

3
Вам слід задати нове запитання, ~ "Зберегти історію zsh у кількох вікнах терміналів", припускаючи, що такого ще не існує. Цілком нормально - навіть заохочується - відповісти на власне запитання, якщо це гарне питання.
Олі

1

Я давно хотів цього, особливо можливості отримати команду за тим, де вона була запущена для повторного виконання нового проекту (або пошуку каталогу за допомогою команди). Так я поклав цей інструмент , який поєднує попередні рішення для зберігання глобальної історії CLI з інтерактивним інструментом зібрання під назвою percol (відображений на C ^ R). На першому апараті, який я почав використовувати, він все ще гладкий, тепер він має 2-річну історію CLI.

Він не псується з локальною історією CLI, що стосується клавіш зі стрілками, але дозволяє досить легко отримати доступ до глобальної історії (яку ви також можете зіставити на щось інше, ніж C ^ R)


це для zsh?
sjas

1
так, я зробив це для zsh спочатку. Зрозумів, що це працює і на рибу, і на рибу. Дайте мені знати, працює вона чи ні. Я його не змінював деякий час, і я не впевнений, наскільки чіткий я був у своїх інструкціях із встановлення
Gordon Wells

1

Тому що я віддаю перевагу нескінченній історії, яка зберігається у власному файлі. Я створюю цю конфігурацію на основі https://stackoverflow.com/a/19533853/4632019 :

export HISTFILESIZE=
export HISTSIZE=
export HISTTIMEFORMAT="[%F %T] "

export HISTFILE=~/.bash_myhistory
PROMPT_COMMAND="history -a; history -r; $PROMPT_COMMAND"

-1

Ось фрагмент з мого .bashrc та короткі пояснення, де потрібно:

# The following line ensures that history logs screen commands as well
shopt -s histappend

# This line makes the history file to be rewritten and reread at each bash prompt
PROMPT_COMMAND="$PROMPT_COMMAND;history -a; history -n"
# Have lots of history
HISTSIZE=100000         # remember the last 100000 commands
HISTFILESIZE=100000     # start truncating commands after 100000 lines
HISTCONTROL=ignoreboth  # ignoreboth is shorthand for ignorespace and     ignoredups

HISTFILESIZE та HISTSIZE - це особисті переваги, і ви можете змінити їх відповідно до своїх смаків.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.