Постановка задачи
Я следовал многочисленным примерам креативных решений с историей bash, например:
# simplified example
PROMPT_COMMAND='history -a; history -c; history -r'
... но, похоже, это работало с перебоями. Если файл истории уже существует с предыдущей историей, то все в порядке.
Другая важная информация
- Версии bash: 3.2.51, 4.1.2 и 4.2.45
- В 4.2.x такой проблемы, похоже, нет, но это не установка по умолчанию.
- ОС: Linux и Solaris
- домашний каталог смонтирован по NFS
Диагностические шаги
Я избавился от своего .bashrc
и установил следующее .bash_profile
:
HISTFILE=$HOME/.bash_history.test
Затем я бы запустил оболочку входа (например, ssh на другую машину) и сделал бы что-то вроде следующего:
~ cat .bash_history.test
cat: .bash_history.test: No such file or directory
~ history
1 cat .bash_history.test
2 history
~ history -a
~ !-3
cat .bash_history.test
cat: .bash_history.test: No such file or directory
Файл истории не будет добавлен history -a
в следующих случаях:
- Файл еще не существует.
- Файл пуст или содержит только новые строки; даже пробелы заставят его работать
... однако, когда оболочка покидает егоделаетсоздайте его. После этого history -a
работает как и ожидалось... за исключением случаев, когда PROMPT_COMMAND="history -a; history -c; history -r"
. Когда у меня был этот набор, даже выход из оболочки не создавал файл истории (если я не запускал его exec bash
сначала).
Затем я попробовал нестандартную установку bash (4.2.x), и проблема не проявилась.
решение1
Эта ветка рассылкипохоже, объясняет эти проблемы; цитата из 2-го сообщения:
Текущий код в bashhist.c:maybe_append_history() (который существует уже не менее 15 лет), похоже, не обрабатывает случай, когда количество строк истории в текущем сеансе равно количеству записей в списке истории. То есть, код не будет добавлять новые строки, если он считает, что не было никаких строк, считанных из файла истории при запуске оболочки. Это кажется неправильным, и я приложил патч, который это исправляет. Однако код существует в своей текущей форме так долго, что мне интересно, есть ли для этого какая-то другая причина.
(Чет Рэми, список рассылки GNU bash)
Кроме того,журнал измененийдля 4.2 есть следующий текст:
+ 8/13
+ ----
+bashhist.c
+ - in maybe_append_history, change check for history_lines_this_session
+ so that we append the lines to the file if it's equal to the value
+ returned by where_history(). This means that without this change,
+ the history won't be appended if all the lines in the history list
+ were added in the current session since the last time the history
+ file was read or written. Fixes bug reported by Bruce Korb
+ <[email protected]>
(git.savannah.gnu.org, bash git repo)
Очевидно, что для решения этой проблемы нам необходимо установить более новую версию bash.
Надеюсь, это поможет кому-то еще в будущем.