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

Я использовал ответ в https://unix.stackexchange.com/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"

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

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

В качестве примера выходы (T1 обозначает клемму 1 и T2 клемму 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

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

19
задан 13 April 2017 в 15:37

4 ответа

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

0
ответ дан 13 April 2017 в 15:37

Похоже, вы пытаетесь получить доступ к истории другого терминала до синхронизации. 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 вы получаете новое приглашение, которое запускает [ 113] и синхронизирует вашу историю, и поэтому я ожидаю, что эта стрелка вверх получит cd вместо ls, как вы хотели. К сожалению, я не думаю, что есть способ сделать синхронизацию мгновенной во всех терминалах без выполнения каких-либо команд, как вам кажется; фактически это потребовало бы, чтобы все ваши сеансы входа в систему постоянно синхронизировали свои списки истории, что было бы огромной тратой процессорной и дисковой пропускной способности.

0
ответ дан 13 April 2017 в 15:37

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

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
0
ответ дан 13 April 2017 в 15:37

добавьте эти строки в ваш файл .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, привязанные к tty (ps a сообщает только процессы, привязанные к tty)

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

0
ответ дан 13 April 2017 в 15:37

Другие вопросы по тегам:

Похожие вопросы: