Назад | Перейти на главную страницу

Странное поведение истории bash при запуске нескольких сеансов

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

Кто-нибудь может это объяснить?

Есть ли способ управлять историей таким образом, чтобы я мог повторно использовать историю из определенного окна?

Чтобы сначала понять поведение истории bash, вы должны знать следующее:

  1. История есть в файле истории.
  2. История bash-процесса хранится в памяти.
  3. История в памяти одного процесса bash не синхронизируется с историей в памяти любого другого процесса bash.
  4. История в памяти процесса bash не синхронизируется с историей в файле, если явно не запрашивается или во время какого-либо конкретного события (см. Ниже).

При использовании настроек по умолчанию жизненный цикл сеанса bash в отношении истории выглядит следующим образом:

  1. Во время запуска bash прочитает файл истории. Теперь содержимое файла истории находится в памяти процесса bash.
  2. При нормальном использовании обрабатывается только история в памяти.
  3. Во время выключения история в памяти записывается в файл истории, перезаписывая все предыдущее содержимое файла истории.

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

Прочтите руководство по bash для более подробного объяснения процесса запуска и выключения.

Обратите внимание, что под настройками по умолчанию я имею в виду настройки по умолчанию из bash. Ваш дистрибутив мог предоставить .bashrc (или /etc/bash.bashrc), которые меняют это поведение.

Включив опцию оболочки histappend вы можете указать bash добавить, а не перезаписывать файл истории. Вы можете включить histappend используя команду shopt -s histappend. Чтобы эта опция всегда была включена, вы должны поместить команду в свой .bashrc (или другой файл инициализации). Узнать больше о shopt команда в руководство по bash

Обратите внимание, что включение histappend не сильно уменьшит, казалось бы, недетерминированное поведение. Это потому, что каждый сеанс bash по-прежнему имеет в памяти свою историю. Можно иметь в основном синхронизированную историю bash. Существует руководство, как заставить каждый процесс bash иметь в основном синхронизированную историю в поток при переполнении стека.

используя встроенную команду history вы можете явно указать bash читать историю из файла в память или записывать из памяти в файл. Например: history -r прочитает содержимое файла и добавит его в историю в памяти. history -w запишет текущую историю из памяти в файл, перезаписав предыдущее содержимое. Это в основном то, что происходит при выключении. Узнать больше о history команда в руководство по bash

Для полноты, вот список внутренних переменных, которые изменяют поведение истории:

  • HISTFILE: файл для чтения и записи истории.
  • HISTFILESIZE: максимальное количество строк для файла истории.
  • HISTSIZE: максимальное количество строк в истории в памяти.
  • HISTCONTROL, HISTIGNORE, HISTTIMEFORMAT: не имеет отношения к данному обсуждению. Прочтите руководство по bash для подробностей.

http://www.gnu.org/software/bash/manual/bashref.html#Using-History-Interactively

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

AFAIK, команды bash сохраняются после завершения сеанса SSH. Таким образом, команды не сохраняются при аварийном завершении сеанса (например, из-за сбоя сети). Я говорю здесь о сессиях SSH. Местные терминалы могут использовать аналогичный подход.

При одновременном открытии нескольких сеансов команды, введенные в одном сеансе, не видны в другом, пока они оба активны. Однако вы увидите эти команды, когда завершите сеанс и снова откроете его.