Добавьте следующее к ~/.bashrc
# Avoid duplicates
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
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"
Я могу предложить фиксацию для той последней: удостоверьтесь, что огибающий переменный HISTCONTROL не указывает "ignorespace" (или "ignoreboth").
Но я чувствую Вашу боль с несколькими параллельными сессиями. Это просто не обрабатывается хорошо в ударе.
Чтобы сделать это, необходимо будет добавить две строки к Вашему ~/.bashrc
:
shopt -s histappend
PROMPT_COMMAND="history -a;history -c;history -r;$PROMPT_COMMAND"
От man bash
:
Если опция оболочки histappend включена (см. описание shopt под SHELL ВСТРОЕННЫЕ КОМАНДЫ ниже), строки добавляются в файл истории, иначе файл истории перезаписывается.
Я не знаю ни о каком способе использовать 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
Можно использовать history -a
для добавления истории текущей сессии к histfile затем используйте history -r
на других терминалах для чтения histfile.
При необходимости в ударе или zsh истории, синхронизирующей решение, которое также решает проблему ниже, то посмотрите его по http://ptspts.blogspot.com/2011/03/how-to-automatically-synchronize-shell.html
Проблема следующая: у Меня есть два окна A оболочки и B. В окне A оболочки я работаю sleep 9999
, и (не ожидая сна для окончания) в окне B оболочки я хочу смочь видеть sleep 9999
в истории удара.
Причина, почему большинство других решений здесь не решит эту проблему, состоит в том, что они пишут свои изменения истории в использование файла истории PROMPT_COMMAND
или PS1
, оба из которых выполняются слишком поздно, только после sleep 9999
команда закончилась.
Вот моя попытка совместного использования истории сессии Bash. Это включит совместное использование истории между сессиями удара способом, как которые счетчик истории не становится перепутанным и расширение истории !number
будет работать (с некоторыми ограничениями).
Используя версию 4.1.5 Bash в соответствии с Ubuntu 10.04 LTS (Ясный 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
Добавьте справедливую вводимую строку к $HISTFILE
(значение по умолчанию .bash_history
). Это вызовет $HISTFILE
вырасти одной строкой.
Установка специальной переменной $HISTFILESIZE
к некоторому значению заставит Bash усекать $HISTFILE
быть не более, чем $HISTFILESIZE
строки путем удаления самых старых записей.
Очистите историю рабочей сессии. Это уменьшит счетчик истории суммой $HISTSIZE
.
Считайте содержание $HISTFILE
и вставьте их в к текущей под управлением истории сессии. это повысит счетчик истории суммой строк в $HISTFILE
. Обратите внимание что количество строки $HISTFILE
не обязательно $HISTFILESIZE
.
history()
функционируйте переопределяет встроенную историю, чтобы удостовериться, что история синхронизируется, прежде чем она будет отображена. Это необходимо для расширения истории числом (больше об этом позже).
Шаг 1 гарантирует, что команда от текущей рабочей сессии записана в глобальный файл истории.
Шаг 4 гарантирует, что команды от других сессий вкладывают чтение к текущей истории сессии.
Поскольку шаг 4 повысит счетчик истории, мы должны уменьшить счетчик в некотором роде. Это сделано на шаге 3.
На шаге 3 счетчик истории уменьшается $HISTSIZE
. На шаге 4 счетчик истории повышен количеством строк в $HISTFILE
. На шаге 2 мы удостоверяемся что количество строки $HISTFILE
точно $HISTSIZE
(это означает это $HISTFILESIZE
должен совпасть с $HISTSIZE
).
При использовании расширения истории числом необходимо всегда сразу искать число перед использованием его. Это не означает дисплея подсказки удара между поиском числа и использованием его. Это обычно означает, не входят и никакой ctrl+c.
Обычно, после того как у Вас есть больше чем одна сессия Bash, нет никакой гарантии вообще, что расширение истории числом сохранит свое значение между двумя дисплеями подсказки Bash. Поскольку, когда PROMPT_COMMAND
выполняется история от всех других сессий 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()
таким образом, это не выполняется каждый раз. Например, это не должно выполняться после a CTRL+C
на подсказке. Я часто использую CTRL+C
отбрасывать долгую командную строку, когда я решаю, что не хочу выполнять ту строку. Иногда я должен использовать CTRL+C
остановить сценарий завершения Bash.
Команды от текущей сессии должны всегда быть новыми в истории текущей сессии. Это будет также иметь побочный эффект, что данное число истории сохраняет свое значение для записей истории от этой сессии.
history -n
потому что это портит счетчик истории. Кроме того, я нашел history -n
быть слишком ненадежным.
– lesmana
16.09.2011, 15:02
history -a
, без -c
и -r
, лучше мудрый удобством использования (хотя это не что вопрос, который задают). Это означает команды, которые Вы выполняете, доступны немедленно в новых оболочках даже прежде, чем выйти из текущей оболочки, но не в параллельном выполнении оболочек. Таким образом, Стрелка все еще всегда выбирает последние управляемые команды текущей сессии, которую я нахожу намного менее сбивающими с толку.
– Jo Liss
04.02.2012, 17:15
Можно отредактировать подсказку Bash для выполнения "истории-a" и "истории-r" что предложенный Muerr:
savePS1=$PS1
(в случае, если Вы портите что-то, которое почти гарантируется),
PS1=$savePS1`history -a;history -r`
(обратите внимание, что это обратные галочки; они выполнят историю-a и историю-r на каждой подсказке. Так как они не производят текста, Ваша подсказка будет неизменна.
После того как у Вас есть своя переменная PS1, настраивает способ, которым Вы хотите, устанавливаете ее постоянно она в Вашем ~/.bashrc файл.
Если Вы хотите вернуться к своей исходной подсказке при тестировании сделайте:
PS1=$savePS1
Я сделал основное тестирование на этом, чтобы гарантировать, чтобы оно отсортировало работ, но не могло говорить ни с какими побочными эффектами от выполнения history -a;history -r
на каждой подсказке.
Так, это - все мое связанное с историей .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"
Протестированный с ударом 3.2.17 на Mac OS X 10.5, колотите 4.1.7 на 10,6.
sleep 9999
, и (не ожидая сна для окончания) в окне B оболочки я хочу смочь видеть sleep 9999
в истории удара. решение kch's
– pts
25.03.2011, 15:43
href
это обновляет историю моего текущего терминала немедленно и очищает файл истории в процессе. Каждый раз, когда я открываю новый терминал, та очистка/синхронизация выполняется в моем bashrc файле, таким образом, новый терминал имеет последнюю историю. Я использую это наряду с history -a
– trusktr
16.10.2012, 18:56
export
переменные: Вы определяете их в .bashrc
таким образом, они будут определены в каждой оболочке (даже в неинтерактивных, который также расточителен)
– dolmen
21.06.2016, 17:44
Вот альтернатива, которую я использую. Он громоздкий, но это решает проблему, что @axel_c упомянул, где иногда вы можете иметь отдельный экземпляр истории в каждом терминале (один для make, один для мониторинга, один для vim и т. Д.).
Я держу отдельный прилагаемый файл истории, который я постоянно обновляю. У меня есть следующее сопоставлено на горячую клавишу:
history | grep -v history >> ~/master_history.txt
Это добавляет всю историю от текущего терминала в файл, называемый Master_History.txt в вашем доме.
У меня также есть отдельная горячая клавиша для поиска в файле Master History:
cat /home/toby/master_history.txt | grep -i
Я использую CAT | Греп, потому что он оставляет курсор в конце, чтобы войти в мое регулярное выражение. Очень менее уродливый способ сделать это, чтобы добавить пару сценариев на ваш путь для выполнения этих задач, но горячие клавиши работают в моих целях. Я также периодически потянутую историю от других хозяев, на которых я работал, и добавил эту историю для моего файла Master_History.txt.
Всегда приятно быть в состоянии быстро искать и найти это хитрые повторное выражение, которое вы использовали, или что странный Perl One-Liner, который вы придумали 7 месяцев назад.
Вот фрагмент от моего .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
HistFaleize и HiSize - это личные предпочтения, и вы можете изменить их в соответствии с вашими вкусами.
Верно, так что, наконец, это меня раздражало чтобы найти достойное решение:
# 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
Я бы ни в коем случае не хотел, чтобы команда выполняла быть общим
Я решил хранить историю в файле на каждый tty, так как несколько человек могут работать на одном сервере - разделение команд каждого сеанса упрощает аудит.
# 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
Я написал скрипт для создания файла истории для каждого сеанса или задачи, который основан на следующем.
# 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
Здесь я отмечу одну проблему с
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: Как отметили другие пользователи, export не нужен. См: использование export в .bashrc
Вот мое усовершенствование ответа @ 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
Porque prefiero la historia infinita que se guarda en un archivo personalizado. Creo esta configuración basada enhttps://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"
Это работает для 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
Я давно хотел этого, особенно возможность получить команду по тому, где она была запущена, чтобы повторно -выполнить в новом проекте (или найти каталог по команде ). Поэтому я собрал этот инструмент вместе, который сочетает в себе предыдущие решения для хранения глобальной истории CLI с интерактивным инструментом поиска под названием percol (, сопоставленным с C^R ). Это все еще гладко на первой машине, которую я начал использовать, теперь с> 2-летней историей CLI.
Это не влияет на локальную историю командной строки в том, что касается клавиш со стрелками, но позволяет довольно легко получить доступ к глобальной истории (, которую вы также можете сопоставить с чем-то другим, кроме C^R)
Вот решение, которое не смешивает истории отдельных сессий!
В основном нужно хранить историю каждого сеанса отдельно и воссоздавать ее при каждом запросе. Да, он использует больше ресурсов, но он не такой медленный, как может показаться -задержка становится заметной, только если у вас более 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
Полное решение, включая некоторые меры безопасности и оптимизацию производительности, см. в этой сути .
Это не совсем ответ на вопрос, или это так. Это зависит от того, как вы на это смотрите. Судя по всему, bash
не поддерживает это из коробки. И не то чтобы просто так, если подумать. Для реализации этого он должен записывать в файл истории (, не дублируя его )перед выполнением каждой команды, и читать каждый раз, когда ему требуется история. Как вы думаете, файла будет достаточно? Ну, вы можете использовать блокировки, но, учитывая, что некоторая индексация будет в порядке, должно быть проще просто использовать какую-то базу данных. И вдобавок ко всему, вы действительно хотите, чтобы у всех оболочек была общая история? Разве вы не используете Up для повторного выполнения команды из текущей оболочки? Вы не используете sudo !!
?
Так что я предлагаю ПОЦЕЛУЙ (быть практичным):
shopt -s histappend
HISTCONTROL=erasedups
Если вы хотите выполнить команду в другой оболочке, выполните history -a
, затем в другой оболочке history -n
, и все готово.
history -a
(...) не инициировал стирающиеся дубликаты согласно этому ответу на историю Bash вопроса: “ignoredups” и “erasedups”, устанавливающий конфликт с общей историей через сессии. Этот ответ также дает последовательностьhistory -<option>
команды, который работает сHISTCONTROL=ignoredups:erasedups
установка. – Piotr Dobrogost 29.02.2016, 22:49export
HISTCONTROL
иPROMPT_COMMAND
переменные: Вы определяете их в.bashrc
таким образом, они будут определены в каждой оболочке (даже в неинтерактивных, который также расточителен). – dolmen 21.06.2016, 17:43