Как получить общую историю битых между разными вкладками

19

Я использовал ответ в /unix//a/1292/41729, чтобы включить совместную историю в реальном времени между отдельными терминалами bash. Как объяснено в ответе выше, это достигается путем добавления:

# avoid duplicates..
export HISTCONTROL=ignoredups:erasedups  
# append history entries..
shopt -s histappend

# After each command, save and reload history
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Это прекрасно работает, если оболочки bash разделены (например, открываются разные терминалы bash с использованием CTRL+ALT+T. Однако это не работает, если я использую tabs(с открытого терминала `CTRL + SHIFT + T), а не новые окна. Почему такая разница в поведении? Как я могу поделиться историей Bash также среди различных вкладок?

ОБНОВЛЕНИЕ: я заметил необычное поведение: если я печатаю, CTRL+Cто последняя команда, набранная на любом из других терминалов (с вкладкой или без), отображается правильно. Это как если бы CTRL + C принудительно очищал историю, чтобы затем правильно делиться.

В качестве примера выходы (Т1 обозначает клемму 1, а Т2 - клемму 2):

T1:
ls -lah <enter>
# the list of files and directory is shown

T2:
cd Documents <enter>

T1:
<up> (i.e. I press the up arrow)
ls -lah #i.e the last command in terminal 1 is shown rather than the last of terminal 2
^C (i.e. I press CTRL+C)
<up>
cd Documents #the last command issued in terminal 2 is correctly displayed

Надеюсь, что это может предложить любую подсказку!

lucacerone
источник
Вы добавили это в свой ~.bashrcфайл? С другой стороны, экспортировать эти переменные бессмысленно; просто впустую пространство окружающей среды.
гейра
@geirha да, я добавил в свой файл .bashrc. Спасибо за комментарий к экспорту.
lucacerone

Ответы:

2

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

Чтобы проверить это, попробуйте этот вариант на своих шагах (я добавил дополнительный <enter>в T1):

T1:
ls -lah <enter>
# the list of files and directory is shown

T2:
cd Documents <enter>

T1:
<enter>
<up> (i.e. I press the up arrow)

С помощью этого дополнительного нажатия Enter вы получаете новое приглашение, которое запускает PROMPT_COMMANDи синхронизирует вашу историю, и поэтому я ожидаю, что эта стрелка вверх получит cdвместо того ls, что вы хотели. К сожалению, я не думаю, что есть способ сделать синхронизацию мгновенной во всех терминалах без выполнения каких-либо команд, как вам кажется; фактически это потребовало бы, чтобы все ваши сеансы входа в систему постоянно синхронизировали свои списки хронологии, что привело бы к огромным потерям производительности ЦП и дисков.

Павел
источник
Вы правы, нажав Enter, он синхронизируется после. Даже если это пустая трата памяти или процессора , как я мог заставить синхронизации (если это слишком много , я всегда могу отключить его, но я хотел бы дать ему попробовать)?
lucacerone
1

Я задал тот же вопрос, и вот ответ, который я придумал ....

HISTSIZE=9000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups

history() {
  _bash_history_sync
  builtin history "$@"
}

_bash_history_sync() {
  builtin history -a         #1
  HISTFILESIZE=$HISTSIZE     #2
  builtin history -c         #3
  builtin history -r         #4
}

PROMPT_COMMAND=_bash_history_sync
Скотт Гудгейм
источник
Источник: unix.stackexchange.com/a/48116/37944
Раду Радеану
два уточнения, прежде чем я попытаюсь: я должен удалить другую историю - варианты тогда? это идет в .bashrc правильно?
lucacerone
к сожалению, это не работает ...
lucacerone
Каждый раз, когда HISTFILESIZEон изменяется, он автоматически пытается обрезать существующий файл истории. Изменение HISTSIZEимеет аналогичное влияние на текущую историю. Для справки смотрите комментарий в variables.cbash src прямо перед этим sv_histsize.
Брайан Ванденберг
1

добавить эти строки в ваш .bashrcфайл

# avoid duplicates..
export HISTCONTROL=ignoredups:erasedups  
# append history entries..
shopt -s histappend

trap 'history -r' USR1 
export PROMPT_COMMAND="history -a ; history -c; ps a | awk '/ bash$/ {system (\"kill -USR1 \" \$1)}'; $PROMPT_COMMAND"

нота:

Изначально я выполнял тестовый отсек, отправляя сигнал USR1 на bash с помощью killall, позже я решил использовать уникальное имя оболочки, копию bash с именем testshell, чтобы избежать уничтожения моих собственных оболочек, которые могли работать (например, процессы cron), но, как ни странно, это было не так. работает.

Killall не был достаточно избирательным, я заменил его сценарием, который убивает только процессы bash, ps aпривязанные к tty ( сообщает только процессы, связанные с tty)

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

Эммануэль
источник
Вам не нужен новый пользователь и другая оболочка, вы можете просто killallотправить сигнал только процессам того же пользователя с дополнительным -uаргументом , e.g. -u $ (whoami) `.
Филипп Вендлер
Я думаю, что синтаксис для csh неправильный ... @PhilippWendler не могли бы вы уточнить немного?
lucacerone
Вопрос о bash, поэтому я использовал синтаксис bash. Я не знаю csh. Для bash killall -q -USR1 -u $(whoami) bashотправляет сигнал USR1 всем процессам bash текущего пользователя.
Филипп Вендлер
@Philippy tyt между прочим, я не тестировал специальное решение для оболочки, это было для исправления случая, когда запускался скрипт cron bash.
Эммануэль
@ LucaCerone я переписал, кажется, работает
Эммануэль
0

У меня было такое же странное поведение в Yakuake, когда я пытался создать сложное приглашение bash, которое показывало бы количество других логинов. Количество не увеличивается для вкладок. Мой обходной путь - заставить Yakuake bashснова запускаться на каждой новой вкладке, по сути, начиная bash в bash. Это начало работать без нареканий. Может быть, это тоже поможет тебе. Мое слепое предположение состоит в том, что графический интерфейс для консольных загрузок настраивает bash, а затем передает их экземплярам bash. Может быть, это быть в состоянии возиться с ними.

Барафу Альбино
источник
Я пытался загрузить bash в bash, но безуспешно :(
lucacerone