Можно ли сделать запись в .bash_history незамедлительной?

125

Я часто открывать много и много терминалов [Сейчас у меня есть 7 открыть на этом рабочем пространстве] , и я часто поиска historyс , grepчтобы найти команду , я только что написал недавно, но я не хочу , чтобы выследить терминал , а затем выполните прокрутку вверх и охотиться за ним больше и т. д. Иногда мои терминалы закрываются без «выхода», и все, что я написал, теряется [Иногда мне нужно что-то, что я написал в терминале, который был убит].

Так есть ли способ сделать так, чтобы каждый терминал немедленно записывал в .bash_history? или хотя бы раз в минуту или что-то в этом роде?

Matt
источник
2
Обычно я использую control-rдля обратного поиска в истории команд одного bash. Удобнее, чем history | grepесли вам не нужно регулярное выражение.
Питер Кордес

Ответы:

93

Простое решение, как описано в Обновлении Bash History в реальном времени .

Он говорит, чтобы поместить эти команды в конфигурации .bashrc:

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

Первая команда изменяет .historyрежим файла для добавления. А вторая настраивает history -aкоманду, которая будет запускаться при каждом приглашении оболочки. -aНемедленно записывает текущие / новые строки в файл истории.

Связано с zsh:

марио
источник
1
ну этот вид работ. Я попытался провести еще одно тестирование, и, похоже, оно работает только с первой командой. это работает правильно для вас?
Мэтт
55

Попробуйте вставить это в свой .bashrc:

shopt -s histappend                      # append to history, don't overwrite it
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Кредит здесь: https://stackoverflow.com/questions/103944/real-time-history-export-amongst-bash-terminal-windows/3055135

history -cочищает историю запущенного сеанса Это уменьшит счетчик истории на величину $HISTSIZE. history -rпрочитайте содержимое $HISTFILEи вставьте их в текущую историю сеанса. Это увеличит счетчик истории на количество строк в $HISTFILE.

Я думаю, это означает, что команды доступны почти сразу (у вас есть один терминал, запись echo 1, второй терминал echo 2, сначала, echo 3и после двойного нажатия стрелки вниз, вы должны быть echo 2доступны. Вы должны выполнить команду в данном терминале, чтобы иметь доступ к тому, что имеет было написано.

вир
источник
Brilliant! Благодарю. Интересно, почему эти параметры не задокументированы в man history...
artfulrobot
10
@artfulrobot: эта команда является bashвстроенной, поэтому она описана в man bash. Вы также можете использовать help history.
Пабук
2
Мой zsh настроен для работы следующим образом: каждая оболочка отслеживает свою СОБСТВЕННУЮ историю (а до этого объединенную историю), и каждая команда добавляется в объединенную историю. Это отличается и лучше, чем всегда перезагружать историю для каждой команды для каждой оболочки, потому что я склонен иметь разные «потоки работы» или «задания» для каждого терминала оболочки. Я думаю, что это разница между этим -rи -cпросто иметь -a.
Стивен Лу
Так что именно вы используете? history -c; history -r? Я думаю, что это лучше для вас, это было бы лучше для меня только иногда, я часто использую несколько оболочек для выполнения одной работы, поэтому я предпочитаю, чтобы история объединялась как можно больше. Я на самом деле возражаю, что команда записывается в историю только после ее завершения. обычно, когда я запускаю ssh-сессию на одном хосте и хочу открыть другой, пока первый еще работает, мне приходится перепечатывать его, потому что он еще не был записан в историю.
субботу
Я думаю, что никогда не задерживался достаточно долго, чтобы понять, как заставить bash одновременно отслеживать параллельные потоки истории (для каждого экземпляра оболочки), одновременно записывая историю в основной файл истории. Zsh делает это намного проще, плюс, кроме того, я определил функцию zsh для записи большого количества необычных метаданных в файл расширенной истории моего устройства. Это стало довольно незаменимым. В любом случае, есть механизмы precmd () и preexec () для zsh, которые посылают аргументы, описывающие введенную команду. Затем становится просто направить это в файлы. history -aможет быть достаточно
Стивен Лу
38

У меня большой файл истории с около 100000 записей, и варианты, которые очищают список истории и читают весь файл истории (используя history -cи history -r), вносят заметную (может быть, 0,2 секунды) задержку перед отображением подсказки. Использование history -nтак, чтобы только новые строки читались из файла истории, быстрее:

shopt -s histappend
PROMPT_COMMAND='history -a;history -n'

PROMPT_COMMAND не нужно экспортировать, потому что это переменная оболочки.

nisetama
источник
Brilliant! Нет больше потерянной истории, когда связь обрывается!
Tobia
Это замечательно. При добавлении в файл и чтении из файла, он будет делиться историей между несколькими терминалами.
августа
3

Примечание для всех других ответов (которые в основном то же самое):

Установка PROMPT_COMMAND="history -a;$PROMPT_COMMAND"в .bashrc(или друзья) достаточно.

Кроме того, вы можете вручную запускать history -aкаждый раз, когда вы хотите «сделать снимок» истории в текущем сеансе.

Команда shopt -s histappendне нужна, потому что history -aвсегда добавляет новые строки в файл и никогда не перезаписывает его. Кроме того, по крайней мере, начиная с Bash 4, histappendэто поведение по умолчанию.

Guss
источник
На моем Mac 10.13.6 казалось, что не работает без shopt -s histappend. Также обратите внимание, что я добавил его в мой~/.bash_profile
ubershmekel
Вероятно, где-то в вашей системе есть другой параметр, который отключен histappend, так как это поведение по умолчанию. Я бы искал это, но у меня нет доступа к Mac.
Гусс