Какие причины могут привести к неожиданному очищению истории bash?

Вопрос или проблема

Сегодня я заметил, что моя история bash полностью очищена. Я не выполнял команды history -c и не удалял файл .bash_history. Помимо удаления файла .bash_history и команды history -c, как еще может быть очищена история bash?

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

Чет Рейми (текущий сопровождающий bash) дал хорошее объяснение условий возникновения этой проблемы:

Текущий код (bash-4.3-devel) работает примерно так, если предположить отсутствие
ошибок (lib/readline/histfile.c:history_do_write()):

  • переименовать (histfile, histfile~)
  • открыть файл с O_CREAT|O_TRUNC
  • выделить буфер, достаточный для хранения всех данных истории
  • записать все записи истории одним вызовом write(2)
  • закрыть файл
  • удалить (histfile~)

Код bash-4.2 работает так же, за исключением того, что он не создает резервную копию
файла истории. Каждый экземпляр оболочки выполняет эти действия при выходе, если
параметр histappend не установлен, как в вашей конфигурации.

Есть несколько причин, по которым файл истории может оказаться с нулевой длиной: может
произойти сбой malloc, или сбой записи. В bash-4.2 уже ничего нельзя сделать с
усеченным файлом истории на этом этапе. В bash-4.3 будет восстановлен предыдущий файл
истории.

Эта тема на рассылке из bug-bash содержит достаточно обсуждений проблем, возможных решений и связанных с ними вопросов.

Есть также некоторые другие возможности:

  • В какой-то момент ваша HISTSIZE или HISTFILESIZE была установлена в 0
  • В какой-то момент ваше history-size в readline было установлено в 0
  • Кто-то, преднамеренно или случайно, стер историю bash (через > "$HISTFILE" или аналогичным образом)

В последнем случае, возможно, вы захотите проверить, что никто не пользовался вашим аккаунтом и не пытался скрыть свои следы грубым способом. Проверьте last, /var/log/auth (или /var/log/secure на CentOS/RHEL), а также любое установленное вами программное обеспечение для учёта процессов и/или аудита.

Как я случайно удалил свою историю bash:

Я разрабатывал собственный альтернативный скрипт readline для терминала с нуля: https://tiswww.cwru.edu/php/chet/readline/rluserman.html

а затем тестировал его в терминале. GNU Readline имеет встроенные инструкции по размеру истории и её сохранению, поэтому размер истории может быть установлен по умолчанию, и таким образом вся ваша история может быть стерта.

Восстановление истории, если она осталась в памяти:

Если вы поймаете это до перезагрузки или если терминал был оставлен открытым до очистки, вы можете найти свою историю в памяти. Запустите history | cut -c 8- > histback_user1.txt на всех открытых терминалах и для каждого пользователя. Если это создаст файл с вашей расширенной историей, то вы сможете заменить ~/.bash_history на histback_user1.txt. Также проверьте историю всех пользователей, недавно вошедших в систему, а также историю root. Удалить историю bash можно случайно при множестве обстоятельств, поэтому, если вы хотите быть уверены в отсутствии потерь в истории, вам нужен ежедневный скрипт резервирования.

.

Ответ или решение

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

Теория

История команд bash хранится в файле, который обычно называется .bash_history. При завершении сеанса bash, команды, вводимые вами во время этого сеанса, записываются в этот файл, что позволяет вам просматривать историю даже после перезапуска сеанса. Однако существуют различные факторы, которые могут привести к тому, что этот файл станет пустым или его содержимое будет утеряно.

Основные причины обнуления истории bash:

  1. Состояние гонки при завершении нескольких сеансов: Когда вы закрываете несколько окон терминала одновременно, возникает ситуация гонки. Поскольку блокировка файла истории в bash не используется, два сеанса могут конкурировать за доступ к файлу одновременно. Это может привести к тому, что один из сеансов перезапишет изменения другого, что в результате может оставить файл пустым.

  2. Сбои при записи: Согласно объяснению от Чета Рэйми, текущий процесс записи истории bash включает несколько шагов, таких как выделение памяти для буфера и запись данных за один вызов. Если один из этих шагов (например, выделение памяти или запись) завершится с ошибкой, файл может остаться пустым.

  3. Настройка переменных окружения: Если переменные HISTSIZE или HISTFILESIZE в bash были случайно установлены в 0, это могло бы привести к обнулению истории. Подобный эффект может возникнуть и при настройке параметров readline, если history-size установили в 0.

  4. Умышленное или случайное удаление истории: История может быть стерта вручную. Например, команда > "$HISTFILE" в скрипте или командной строке сбросит файл до нулевой длины. Не исключена возможность, что кто-то с доступом к вашей учётной записи мог выполнить такие действия.

Примеры

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

В другой ситуации, если параметр HISTSIZE был настроен на 0 в вашем ~/.bashrc или ином конфигурационном файле, это приведет к тому, что никакие команды не сохраняются после завершения сеанса.

Применение

Для устранения данной проблемы и предотвращения её повторного возникновения, рассмотрите следующие действия:

  1. Проверьте настройки конфигурации bash: Убедитесь, что HISTSIZE и HISTFILESIZE не равны 0. Это можно сделать, открыв ~/.bashrc и ~/.bash_profile.

  2. Используйте histappend: Чтобы добавить команды к существующей истории, а не перезаписывать её, добавьте shopt -s histappend в ваш файл конфигурации bash.

  3. Регулярное резервное копирование: Настройте автоматический скрипт, который будет ежедневно сохранять копию вашего .bash_history, что сократит риски утраты данных при возникновении ошибок.

  4. Проверка безопасности: Если вы подозреваете внешнее вмешательство, исследуйте журнал доступа last и файлы журналов, такие как /var/log/auth.log или /var/log/secure. Это может предоставить информацию о подозрительной активности в вашей системе.

  5. Использование иных инструментов и форматов: Рассмотрите возможность использования инструментов, таких как Zsh или Fish, которые могут иметь более безопасное управление историей и дополнительные функции для восстановления утраченной информации.

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

Оцените материал
Добавить комментарий

Капча загружается...