Сохранить историю Bash в нескольких окнах терминала

525

У меня постоянно открыто более одного терминала. В любом месте от двух до десяти, делая различные биты и качки. Теперь допустим, я перезагружаюсь и открываю другой набор терминалов. Некоторые помнят определенные вещи, некоторые забывают.

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

  • Помнит все с каждого терминала
  • Мгновенно доступен с любого терминала (например, если я lsв одном, переключаюсь на другой уже работающий терминал, а затем нажимаю вверх, lsпоявляется)
  • Не забывает команду, если перед командой есть пробелы.

Что-нибудь, что я могу сделать, чтобы заставить bash работать так больше?

Oli
источник
57
Я вижу преимущество этого, но лично я ненавижу это в своей оболочке. Я обычно держу в своем терминале 3 или 4 вкладки для очень специфического использования: одну для запуска make, одну с vi, другую для запуска и т. Д. Поэтому, когда я компилирую, я перехожу на вкладку 1, открываю и make и так далее. Это очень продуктивно для меня. Так что, если вдруг я перейду на вкладку «make» и нажму, и появится какая-нибудь случайная команда grep, я действительно разозлюсь! Просто личное примечание, хотя
axel_c
4
@axel_c это достаточно верно. Я не могу придумать разумного способа сделать это, когда существующие терминалы видят только свою историю, а новые видят хронологически точный список команд.
Оли
8
@ Оли написал: «Я не могу придумать разумного способа сделать это, когда существующие терминалы видят только свою собственную историю, а новые видят хронологически точный список команд». Как насчет (не опробовано) export PROMPT_COMMAND="history -a; $PROMPT_COMMAND". Существующие оболочки добавят каждую команду в файл истории, чтобы новые оболочки могли видеть их, но отображать только свои истории.
Крис Пейдж
2
Вы хотите, чтобы история все хранилась отдельно или была объединена в один файл истории?
kbyrd
3
Краткий ответ: он не предназначен для разработчиков bash. Решения, основанные на промывке и перечитывании истории, вероятно, работают, но остерегайтесь Шлемиэля Художника . Проще говоря: объем обработки между каждой командой пропорционален размеру истории.
Стефан Гурихон

Ответы:

328

Добавьте следующее в ~ / .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
@ Суан, мне кажется, это правильно на основании команд. Я обнаружил, что мы можем выполнить нулевую команду (просто нажмите клавишу ввода), чтобы получить историю для обновления.
мудрец
3
На самом деле history -a(...) не запускает удаление дубликатов в соответствии с этим ответом на вопрос Bash history: настройки ignoredups и erasedups конфликтуют с общей историей между сеансами . Этот ответ также дает последовательность 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.

KCH
источник
3
Хм .. Это убивает возможность использовать $! 34, так как номера команд меняются в каждом приглашении. Есть ли обходной путь @Davide @Schof @kch?
5
Используйте это, чтобы получить бесконечную историю: bash вечная история . ОДНАКО, это дополняет код выше, так как он не будет автоматически перезагружен.
7
К вашему сведению, ни одно из упомянутых здесь решений не может решить следующую проблему. У меня есть два окна оболочки A и B. В окне оболочки A я запускаюсь sleep 9999, и (не дожидаясь окончания сна) в окне оболочки B я хочу видеть sleep 9999историю bash.
оч
1
@pts Я тоже стремился к живому поведению, но потом понял, что удобнее иметь конкретные истории терминала, которые облегчают работу над разными вещами в разных терминалах. Я нашел это очень полезным: stackoverflow.com/questions/338285/#answer-7449399 Исходя из этого, я сделал себе псевдоним, hrefкоторый мгновенно обновляет историю моего текущего терминала и в процессе очищает файл истории. Всякий раз, когда я открываю новый терминал, эта очистка / синхронизация выполняется в моем файле bashrc, поэтому новый терминал имеет новейшую историю. Я использую это вместе сhistory -a
trusktr
6
exportПеременным нет причин : вы определяете их .bashrcтак, чтобы они были определены в каждой оболочке (даже в неинтерактивных, что также расточительно)
дольмен
117

Вот моя попытка поделиться историей сессий 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).

Об ограничениях расширения истории:

При использовании расширения истории по номеру, вы всегда должны искать номер непосредственно перед его использованием. Это означает, что между поиском номера и его использованием не должно отображаться приглашение bash. Это обычно означает, что нет ввода и не 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приглашения. Я часто использую, CTRL+Cчтобы отменить длинную командную строку, когда я решаю, что я не хочу выполнять эту строку. Иногда мне нужно использовать, CTRL+Cчтобы остановить скрипт завершения Bash.

  • Команды из текущего сеанса всегда должны быть самыми последними в истории текущего сеанса. Это также будет иметь побочный эффект, заключающийся в том, что данный номер истории сохраняет свое значение для записей истории из этого сеанса.

lesmana
источник
1
Почему бы не "history -n" (перезагрузить строки, которые еще не загружены) вместо "history -c; history -r"?
Грэм
@Graham: я не хотел использовать, history -nпотому что это портит счетчик истории. Кроме того, я нашел history -nслишком ненадежным.
Лесмана
1
Один недостаток: Команды с многострочными строками обычно все еще сохраняются в текущем сеансе. С помощью этого трюка они мгновенно разбиваются на отдельные строки. Использование -n для -c -r не помогает, равно как и cmdhist или lithist. Я не думаю, что есть обходной путь в этой точке.
Джо Лисс
24
Попробовав это немного, я обнаружил, что запуск только history -aбез -cи -rлучше в плане удобства использования (хотя вопрос не в этом). Это означает, что команды, которые вы запускаете, доступны мгновенно в новых оболочках даже до выхода из текущей оболочки, но не в одновременно работающих оболочках. Таким образом, Arrow-Up по-прежнему всегда выбирает команды последнего запуска текущего сеанса , что я нахожу гораздо менее запутанным.
Джо Лисс
Исключительно хороший ответ, он работает надежно, в отличие от более распространенного «history -a; history -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 (см. Описание shopt в разделе «Команды SHELL BUILTIN» ниже), строки добавляются в файл истории, в противном случае файл истории перезаписывается.

Крис Даун
источник
10

Вы можете отредактировать приглашение BASH, чтобы запустить «history -a» и «history -r», которые предложил Muerr:

savePS1=$PS1

(если вы что-то испортили, что почти гарантировано)

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

(обратите внимание, что это обратные тики; они будут запускать history -a и history -r в каждом приглашении. Поскольку они не выводят никакого текста, ваше приглашение не изменится.

После того как переменная PS1 настроена так, как вы хотите, установите ее в файле ~ / .bashrc навсегда.

Если вы хотите вернуться к исходному приглашению во время тестирования, выполните:

PS1=$savePS1

Я провел базовое тестирование, чтобы убедиться, что оно работает, но не могу говорить о каких-либо побочных эффектах от запуска history -a;history -rв каждом приглашении.

Schof
источник
2
Решение КЧ работает лучше, чем у меня. Сейчас я использую его решение в моем .bashrc.
9

Если вам нужно решение для синхронизации истории bash или zsh, которое также решает проблему, приведенную ниже, посмотрите ее по адресу http://ptspts.blogspot.com/2011/03/how-to-automatics-synchronize-shell.html.

Проблема заключается в следующем: у меня есть два окна оболочки A и B. В окне оболочки A я запускаюсь sleep 9999, и (не дожидаясь окончания сна) в окне оболочки B я хочу видеть sleep 9999историю bash.

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

PTS
источник
1
Это хорошее решение, но у меня есть несколько вопросов. 1. Могу ли я использовать оригинальный файл .bash_history, я не хочу, чтобы другой файл истории bash существовал в моем $ HOME 2. Может быть, вам стоит подумать об этом для установки репозитория github.
Вейнхамз
Кажется, отладочный хук конфликтует с bashdb, последующим выводом каждый раз, когда я запускаю сеанс bash. `` `bash debugger, bashdb, выпуск 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]:
неверный
@Techlive Zheng: 1. Исходная .bash_history намеренно не поддерживается, потому что .merged_bash_history использует другой формат файла, поэтому в случае неудачной загрузки .merged_bash_history, bash не будет случайно забивать накопленную историю. Надежность конструкции, будет сохранена как есть. 2. Репозиторий github - хорошая идея в целом, но у меня нет времени, чтобы поддержать это для этого проекта, поэтому я не делаю этого. - Да, это конфликтует с bashdb, и нет простого решения (они используют одни и те же хуки). Я не планирую работать над исправлением, но я принимаю исправления.
оч.
Хорошо, спасибо. Я придумал гораздо более простой и лучший sulotion.
Вейнхамз
@TechliveZheng: Не могли бы вы поделиться с нами вашим простым и лучшим решением, чтобы мы все могли извлечь из него уроки? (Если это так, пожалуйста, добавьте ответ на вопрос.)
оч.
8

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

jtimberman
источник
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.

Всегда приятно иметь возможность быстро найти и найти то хитрое регулярное выражение, которое вы использовали, или тот странный perl-однострочный текст, с которым вы столкнулись 7 месяцев назад.

Тоби
источник
6

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

Но я чувствую твою боль от нескольких одновременных сеансов. Это просто плохо обрабатывается в bash.

jmanning2k
источник
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'.

Вы могли видеть, что некоторые команды явно не работают: "history -n history -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 = "echo 123"; $ PROMPT_COMMAND'):

123

Запустите следующее:

$ echo 3

выход:

3
123

«history -a» используется для записи команд истории в памяти в ~ / .bash_history

«history -c» используется для очистки истории команд в памяти

«history -r» используется для чтения команд истории из ~ / .bash_history в память

Смотрите объяснение команды истории здесь: http://ss64.com/bash/history.html

PS: как отметили другие пользователи, экспорт не нужен. Смотрите: используя экспорт в .bashrc

fstang
источник
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

simotek
источник
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
Мульки
источник
к сожалению вопрос строго для bash :-)
Jaleks
1
его первый результат на Google , когда я искать Zsh , а также ... Думал , что это может помочь
Мульки
3
Вам следует задать новый вопрос: ~ «Сохранить историю zsh в нескольких окнах терминала», предполагая, что она еще не существует. Совершенно нормально - даже рекомендуется - ответить на свой вопрос, если это хороший вопрос.
Оли
1

Я давно хотел этого, особенно возможность получить команду, по которой она была выполнена, для повторного выполнения в новом проекте (или найти каталог по команде). Поэтому я собрал этот инструмент , который сочетает в себе предыдущие решения для хранения глобальной истории CLI с интерактивным инструментом под названием percol (сопоставленным с C ^ R). Это все еще замечательно на первой машине, которую я начал использовать, теперь с> 2-летней историей CLI.

Он не вмешивается в локальную историю CLI, поскольку это касается клавиш со стрелками, но позволяет довольно легко получить доступ к глобальной истории (которую можно также сопоставить с чем-то другим, кроме C ^ R)

Гордон Уэллс
источник
это для зш?
Sjas
1
да, я сделал это для Zsh изначально. Получил это работает на рыбу и рыбу тоже, хотя. Дайте мне знать, если это работает или нет. Я не изменил его некоторое время, и я не уверен, насколько ясно я был в моих инструкциях по установке
Гордон Уэллс
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 являются личными предпочтениями, и вы можете изменить их по своему вкусу.

Прыгающий кролик
источник