Як ділитися загальною історією між різними вкладками


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), а не нові вікна. Чому така різниця в поведінці? Як? чи можу я поділитися історією башів також між різними вкладками?

ОНОВЛЕННЯ: Я помітив незвичну поведінку: якщо я набираю, 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

Сподіваюся, що це може запропонувати будь-яку підказку!


Ви додали це у свій ~.bashrcфайл? З іншого боку, експорт цих змінних є безглуздим; просто витрачає простір середовища.
geirha

@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)

За допомогою цього додаткового натискання клавіші введення ви отримуєте нове підказку, яке запускає 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


дві роз'яснення, перш ніж спробувати: чи слід видалити інші параметри історії - тоді? це входить .bashrc так?
лукацерон

на жаль, це не працює ...
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, щоб битись з killall, пізніше я подумав використати унікальне ім'я оболонки, баш-копію з назвою testhell, щоб уникнути вбивства моїх власних оболонок, які могли працювати (наприклад, процеси cron), але дивним чином це не було робочий.

Кіллалл був недостатньо вибірковим, я замінив його сценарієм, який вбиває лише баш-процеси, тісні до tty ( ps aзвітує лише про процеси, прив'язані до tty)

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


Вам не потрібен новий користувач та інша оболонка, ви можете просто сказати killallнадсилати сигнал лише процесам того самого користувача з додатковим -uаргументом , e.g. -u $ (whoami) `.
Філіп Вендлер

Я думаю, що синтаксис для csh неправильний ... @PhilippWendler ви могли б, будь ласка, детальніше розглянути?
lucacerone

Питання стосується bash, тому я використав синтаксис bash. Я не знаю. Для bash, killall -q -USR1 -u $(whoami) bashпосилає сигнал USR1 для всіх процесів bash поточного користувача.
Філіп Вендлер

@Philipp ty btw Я не перевіряв спеціальне рішення оболонки, це було виправити випадок, коли запускається скрипт bash cron.
Еммануель

@LucaCerone Я переписав, здається, працює
Еммануель

0

Я мав таку ж дивну поведінку в Yakuake, коли намагався створити детальну підказку bash, яка б показувала кількість інших логінів. Кількість не збільшується для вкладок. Моє вирішення полягало в тому, щоб сказати Yakuake бігати bashзнову в кожній новій вкладці, по суті починаючи баш в баш. Це почало працювати бездоганно. Можливо, це теж допоможе вам. Моє сліпе здогадування полягає в тому, що графічний інтерфейс для консольних завантажень bash налаштовує себе, а потім подає їх на екземпляри bash. Можливо, це вміти поспілкуватися з ними.


Я намагався завантажувати баш в баш, але без жодного успіху :(
lucacerone
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.