Можно ли объединить файлы истории в bash?

35

Я регулярно запускаю несколько screenсеансов на своих рабочих столах и серверах Linux.

Проблема в том, что когда я grepпросматриваю историю команд, я обнаружил, что выполнил команду в другом сеансе, и мне нужно отсоединить и повторно присоединить, чтобы получить этот элемент истории.

Можно ли «принудительно» изменить по-разному обновленные истории из нескольких сеансов во все истории?

кроличий садок
источник
Я столкнулся с подобной проблемой, из-за которой я не мог просматривать историю между сеансами терминала. Оказывается, мой файл ~ / .bash_history принадлежал пользователю root и недоступен для записи. Смена владельца / группы на моего пользователя
устранила
аналогично: stackoverflow.com/questions/103944/…
lesmana

Ответы:

41

Есть две вещи, которые вам нужно сделать:

  1. Вставьте команду shopt -s histappendв свой .bashrc. Это добавит к файлу истории вместо того, чтобы перезаписать его.
  2. Также в вашем файле .bashrcinsert PROMPT_COMMAND="$PROMPT_COMMAND;history -a; history -n"и history будет перезаписываться и перечитываться каждый раз, когда bash показывает подсказку.

РЕДАКТИРОВАТЬ: Спасибо e-t172 за history -nтрюк

InnaM
источник
6
Спасибо за это. Я улучшил его, используя PROMPT_COMMAND = "$ PROMPT_COMMAND; history -a; history -n". Таким образом, команды, введенные в других сеансах, немедленно появляются в истории текущего сеанса (ну, сначала нужно нажать Enter, чтобы обновить историю).
Этьен Дечамс
8
Я не PROMPT_COMMANDопределил ранее, поэтому мне пришлось использовать, PROMPT_COMMAND="history -a; history -n"чтобы избежать ошибок.
Уильям Джексон
1
пожалуйста, смотрите ответ superuser.com/a/734410/250287 для правильной истории команд -a, -c и -r.
mtd
Просто предупреждение для новичка: после некоторого переписывания истории я понял, что часто выполняю неправильные команды; когда вы видите в предыдущей строке какую-то команду, вы ожидаете, что стрелка вверх повторит ее, и с этой конфигурацией это уже не всегда так.
Tiago
11

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

# unified bash history
shopt -s histappend
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"

Использование новой строки вместо точки с запятой также является коротким способом решения проблемы отсутствия / дублирования точки с запятой в PROMPT_COMMAND.

Адам Крейн
источник
история -a, -c, а затем -r верна ... это должен быть принятый ответ
mtd
1
Это exportне обязательно. Поскольку предполагается, что устанавливаются параметры интерактивной оболочки, из ~/.bashrcкоторых вызывается каждая вложенная оболочка, поэтому наследование не требуется.
дольмен
Есть ли веская причина не просто использовать PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"вместо этого?
Шесть
Этот порядок потребует сохранения последнего значения выхода перед запуском команд истории, поскольку многие команды подсказок полагаются на него или отображают его.
Адам Крейн
-1

PROMPT_COMMAND не определен по умолчанию в некоторых дистрибутивах. Например, это определено в Arch, но не в Debian.

У меня есть bashrc в моем Dropbox, который я использую во время скачки дистрибутива, и он включает в себя:

PROMPT_COMMAND="$( [ '$PROMPT_COMMAND' ] && echo $PROMPT_COMMAND; )history -a; history -n"
czayas
источник
Ужасное решение основной проблемы программирования оболочки. Правильный путь:PROMPT_COMMAND="$PROMPT_COMMAND; history -a; history -n"
дольмен
Лучше:PROMPT_COMMAND="$PROMPT_COMMAND"$'\n''history -a; history -n'
Дольмен