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


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.