У меня постоянно открыто более одного терминала. В любом месте от двух до десяти, делая различные биты и качки. Теперь допустим, я перезагружаюсь и открываю другой набор терминалов. Некоторые помнят определенные вещи, некоторые забывают.
Я хочу историю, которая:
- Помнит все с каждого терминала
- Мгновенно доступен с любого терминала (например, если я
ls
в одном, переключаюсь на другой уже работающий терминал, а затем нажимаю вверх,ls
появляется) - Не забывает команду, если перед командой есть пробелы.
Что-нибудь, что я могу сделать, чтобы заставить bash работать так больше?
export PROMPT_COMMAND="history -a; $PROMPT_COMMAND"
. Существующие оболочки добавят каждую команду в файл истории, чтобы новые оболочки могли видеть их, но отображать только свои истории.Ответы:
Добавьте следующее в ~ / .bashrc
источник
history -a
(...) не запускает удаление дубликатов в соответствии с этим ответом на вопрос Bash history: настройки ignoredups и erasedups конфликтуют с общей историей между сеансами . Этот ответ также дает последовательностьhistory -<option>
команд, которая работает сHISTCONTROL=ignoredups:erasedups
настройкой.export
вHISTCONTROL
иPROMPT_COMMAND
переменных: вы определяете их ,.bashrc
таким образом они будут определены в каждой оболочке (даже в не-интерактивных, который также является расточительным).Итак, это все, что связано с моей историей
.bashrc
:Протестировано с bash 3.2.17 на Mac OS X 10.5, bash 4.1.7 на 10.6.
источник
sleep 9999
, и (не дожидаясь окончания сна) в окне оболочки B я хочу видетьsleep 9999
историю bash.href
который мгновенно обновляет историю моего текущего терминала и в процессе очищает файл истории. Всякий раз, когда я открываю новый терминал, эта очистка / синхронизация выполняется в моем файле bashrc, поэтому новый терминал имеет новейшую историю. Я использую это вместе сhistory -a
export
Переменным нет причин : вы определяете их.bashrc
так, чтобы они были определены в каждой оболочке (даже в неинтерактивных, что также расточительно)Вот моя попытка поделиться историей сессий Bash. Это позволит совместно использовать историю между сеансами bash таким образом, что счетчик истории не будет перепутан и расширение истории
!number
будет работать (с некоторыми ограничениями).Использование Bash версии 4.1.5 под Ubuntu 10.04 LTS (Lucid Lynx).
Объяснение:
Добавьте только что введенную строку к
$HISTFILE
(по умолчанию.bash_history
). Это приведет$HISTFILE
к росту на одну строку.Установка специальной переменной
$HISTFILESIZE
некоторого значения приведет к тому, что Bash будет усекать$HISTFILE
не длиннее$HISTFILESIZE
строк, удаляя самые старые записи.Очистить историю запущенного сеанса. Это уменьшит счетчик истории на величину
$HISTSIZE
.Прочитайте содержимое
$HISTFILE
и вставьте его в текущую историю сеанса. это увеличит счетчик истории на количество строк в$HISTFILE
. Обратите внимание, что количество строк$HISTFILE
не обязательно$HISTFILESIZE
.history()
Функция отменяет встроенная историю , чтобы убедиться , что история синхронизируется перед его отображением. Это необходимо для расширения истории по номеру (подробнее об этом позже).Больше объяснений:
Шаг 1 гарантирует, что команда из текущего запущенного сеанса будет записана в файл глобальной истории.
Шаг 4 гарантирует, что команды из других сеансов будут считаны в текущую историю сеанса.
Поскольку шаг 4 увеличит счетчик истории, нам нужно каким-то образом уменьшить счетчик. Это делается на шаге 3.
На шаге 3 счетчик истории уменьшается на
$HISTSIZE
. На шаге 4 счетчик истории увеличивается на количество строк в$HISTFILE
. На шаге 2 мы удостоверимся, что количество строк$HISTFILE
точно$HISTSIZE
(это означает, что$HISTFILESIZE
должно быть таким же, как$HISTSIZE
).Об ограничениях расширения истории:
При использовании расширения истории по номеру, вы всегда должны искать номер непосредственно перед его использованием. Это означает, что между поиском номера и его использованием не должно отображаться приглашение bash. Это обычно означает, что нет ввода и не Ctrl + C.
Как правило, если у вас более одного сеанса Bash, нет никакой гарантии, что расширение истории по номеру сохранит свое значение между двумя отображениями приглашения Bash. Потому что, когда
PROMPT_COMMAND
выполняется, история всех других сессий Bash интегрируется в историю текущего сеанса. Если у любого другого сеанса bash есть новая команда, то номера истории текущего сеанса будут другими.Я считаю это ограничение разумным. В любом случае мне приходится каждый раз искать номер, потому что я не могу вспомнить произвольные номера истории.
Обычно я использую расширение истории по номеру, как это
Я рекомендую использовать следующие опции Bash.
Странные баги:
Выполнение команды истории, переданной по каналу, приведет к тому, что эта команда будет дважды указана в истории. Например:
Все будет перечислено в истории дважды. Понятия не имею почему.
Идеи для улучшения:
Измените функцию,
_bash_history_sync()
чтобы она не выполнялась каждый раз. Например, он не должен выполняться послеCTRL+C
приглашения. Я часто использую,CTRL+C
чтобы отменить длинную командную строку, когда я решаю, что я не хочу выполнять эту строку. Иногда мне нужно использовать,CTRL+C
чтобы остановить скрипт завершения Bash.Команды из текущего сеанса всегда должны быть самыми последними в истории текущего сеанса. Это также будет иметь побочный эффект, заключающийся в том, что данный номер истории сохраняет свое значение для записей истории из этого сеанса.
источник
history -n
потому что это портит счетчик истории. Кроме того, я нашелhistory -n
слишком ненадежным.history -a
без-c
и-r
лучше в плане удобства использования (хотя вопрос не в этом). Это означает, что команды, которые вы запускаете, доступны мгновенно в новых оболочках даже до выхода из текущей оболочки, но не в одновременно работающих оболочках. Таким образом, Arrow-Up по-прежнему всегда выбирает команды последнего запуска текущего сеанса , что я нахожу гораздо менее запутанным.Я не знаю ни одного способа использования
bash
. Но это одна из самых популярных функцийzsh
.Лично я предпочитаю
zsh
более ,bash
поэтому я рекомендую попробовать его.Вот часть моей,
.zshrc
которая имеет дело с историей:источник
Для этого вам нужно добавить две строки в ваш
~/.bashrc
:От
man bash
:источник
Вы можете отредактировать приглашение BASH, чтобы запустить «history -a» и «history -r», которые предложил Muerr:
(если вы что-то испортили, что почти гарантировано)
(обратите внимание, что это обратные тики; они будут запускать history -a и history -r в каждом приглашении. Поскольку они не выводят никакого текста, ваше приглашение не изменится.
После того как переменная PS1 настроена так, как вы хотите, установите ее в файле ~ / .bashrc навсегда.
Если вы хотите вернуться к исходному приглашению во время тестирования, выполните:
Я провел базовое тестирование, чтобы убедиться, что оно работает, но не могу говорить о каких-либо побочных эффектах от запуска
history -a;history -r
в каждом приглашении.источник
Если вам нужно решение для синхронизации истории bash или zsh, которое также решает проблему, приведенную ниже, посмотрите ее по адресу http://ptspts.blogspot.com/2011/03/how-to-automatics-synchronize-shell.html.
Проблема заключается в следующем: у меня есть два окна оболочки A и B. В окне оболочки A я запускаюсь
sleep 9999
, и (не дожидаясь окончания сна) в окне оболочки B я хочу видетьsleep 9999
историю bash.Причина, по которой большинство других решений здесь не решают эту проблему, заключается в том, что они записывают свои изменения истории в файл истории с использованием
PROMPT_COMMAND
илиPS1
, оба из которых выполняются слишком поздно, только после завершенияsleep 9999
команды.источник
Вы можете использовать,
history -a
чтобы добавить историю текущего сеанса в исторический файл, а затем использоватьhistory -r
другие терминалы для чтения исторического файла.источник
Итак, в конце концов это раздражало меня, чтобы найти достойное решение:
То, что это делает, является своего рода объединением того, что было сказано в этой теме, за исключением того, что я не понимаю, зачем вам перезагружать глобальную историю после каждой команды. Меня очень мало волнует, что происходит в других терминалах, но я всегда запускаю серию команд, скажем, в одном терминале:
(Упрощенный пример)
И в другом:
Ни за что бы я не хотел, чтобы команда была передана
источник
Вот альтернатива, которую я использую. Это громоздко, но решает проблему, о которой упоминал @axel_c, когда иногда вы можете захотеть иметь отдельный экземпляр истории в каждом терминале (один для make, один для мониторинга, один для vim и т. Д.).
Я храню отдельный файл истории, который постоянно обновляю. У меня есть следующее сопоставлено с горячей клавишей:
Это добавляет всю историю из текущего терминала в файл с именем master_history.txt в вашем домашнем каталоге.
У меня также есть отдельная горячая клавиша для поиска в главном файле истории:
Я использую кошку | grep, потому что он оставляет курсор в конце, чтобы ввести мое регулярное выражение. Менее уродливый способ сделать это - добавить пару скриптов на ваш путь для выполнения этих задач, но горячие клавиши работают для моих целей. Я также периодически извлекаю историю из других хостов, над которыми я работал, и добавляю эту историю в мой файл master_history.txt.
Всегда приятно иметь возможность быстро найти и найти то хитрое регулярное выражение, которое вы использовали, или тот странный perl-однострочный текст, с которым вы столкнулись 7 месяцев назад.
источник
Я могу предложить исправление для этого последнего: убедитесь, что переменная env HISTCONTROL не определяет "ignorespace" (или "ignoreboth").
Но я чувствую твою боль от нескольких одновременных сеансов. Это просто плохо обрабатывается в bash.
источник
Вот мое усовершенствование @ lesmana в ответ . Основное отличие состоит в том, что параллельные окна не делятся историей. Это означает, что вы можете продолжать работать в своих окнах, не загружая контекст из других окон в ваши текущие окна.
Если вы явно введете «историю», ИЛИ если откроете новое окно, вы получите историю из всех предыдущих окон.
Кроме того, я использую эту стратегию для архивирования каждой команды, когда-либо набранной на моей машине.
источник
Я решил поместить историю в файл по отдельности, так как на одном сервере могут работать несколько человек - разделение команд каждого сеанса облегчает аудит.
История теперь выглядит так:
С файлами, похожими на:
источник
Здесь я укажу одну проблему с
а также
Если вы запустите source ~ / .bashrc, $ PROMPT_COMMAND будет выглядеть так:
а также
Это повторение происходит каждый раз, когда вы запускаете 'source ~ / .bashrc'. Вы можете проверить PROMPT_COMMAND после каждого запуска 'source ~ / .bashrc', запустив 'echo $ PROMPT_COMMAND'.
Вы могли видеть, что некоторые команды явно не работают: "history -n history -a". Но хорошая новость заключается в том, что это все еще работает, потому что другие части все еще формируют правильную последовательность команд (просто влечет за собой некоторые дополнительные расходы из-за повторного выполнения некоторых команд. И не настолько чистые.)
Лично я использую следующую простую версию:
который имеет большинство функциональных возможностей, в то время как нет такой проблемы, как указано выше.
Еще одно замечание: в действительности нет ничего волшебного . PROMPT_COMMAND - это просто переменная среды bash. Команды в нем выполняются до того, как вы получите приглашение bash (знак $). Например, PROMPT_COMMAND - это «echo 123», и вы запускаете «ls» в своем терминале. Эффект подобен запуску «ls; echo 123».
вывод (точно так же, как запуск 'PROMPT_COMMAND = "echo 123"; $ PROMPT_COMMAND'):
Запустите следующее:
выход:
«history -a» используется для записи команд истории в памяти в ~ / .bash_history
«history -c» используется для очистки истории команд в памяти
«history -r» используется для чтения команд истории из ~ / .bash_history в память
Смотрите объяснение команды истории здесь: http://ss64.com/bash/history.html
PS: как отметили другие пользователи, экспорт не нужен. Смотрите: используя экспорт в .bashrc
источник
Я написал скрипт для установки файла истории для каждой сессии или задачи, основанной на следующем.
Не обязательно сохранять каждую команду истории, но она сохраняет те, которые меня интересуют, и их проще найти, затем выполнить каждую команду. Моя версия также перечисляет все файлы истории и предоставляет возможность поиска по всем.
Полный источник: https://github.com/simotek/scripts-config/blob/master/hiset.sh
источник
Вот решение, которое не смешивает истории отдельных сессий!
В основном нужно хранить историю каждого сеанса отдельно и воссоздавать ее в каждом приглашении. Да, он использует больше ресурсов, но это не так медленно, как может показаться - задержка становится заметной, только если у вас есть более 100000 записей истории.
Вот основная логика:
Посмотрите эту суть для полного решения, включая некоторые меры предосторожности и оптимизации производительности.
источник
Это работает для ZSH
источник
Я давно хотел этого, особенно возможность получить команду, по которой она была выполнена, для повторного выполнения в новом проекте (или найти каталог по команде). Поэтому я собрал этот инструмент , который сочетает в себе предыдущие решения для хранения глобальной истории CLI с интерактивным инструментом под названием percol (сопоставленным с C ^ R). Это все еще замечательно на первой машине, которую я начал использовать, теперь с> 2-летней историей CLI.
Он не вмешивается в локальную историю CLI, поскольку это касается клавиш со стрелками, но позволяет довольно легко получить доступ к глобальной истории (которую можно также сопоставить с чем-то другим, кроме C ^ R)
источник
Потому что я предпочитаю бесконечную историю, которая сохраняется в пользовательском файле. Я создаю эту конфигурацию на основе https://stackoverflow.com/a/19533853/4632019 :
источник
Вот фрагмент из моего .bashrc и короткие пояснения, где это необходимо:
HISTFILESIZE и HISTSIZE являются личными предпочтениями, и вы можете изменить их по своему вкусу.
источник