Почему история команд сохраняется только при выходе

389
Fidel

Я пытаюсь сохранить другой файл истории для каждой вкладки / терминала, но мне не удается сохранить его сразу после запуска команды. История просто сохраняется, когда я запускаю «выход».

Это проблема, потому что я хочу получить копию истории в случае сбоя терминала или компьютера.

Посмотрев в интернете, вот что у меня есть в моем файле .bashrc:

export HISTFILE="$HOME/HISTORIES/bash_history_$(basename $(tty))_$(date '+%Y-%m-%d_%H-%M-%S_%Z')" export HISTCONTROL=ignoreboth export HISTFILESIZE=10000 export HISTSIZE=10000 shopt -s histappend PROMPT_COMMAND=$(history -a; $PROMPT_COMMAND) 

Есть идеи, что я делаю не так?

Благодарю.

0
Существует ли каталог `$ HOME / HISTORIES`? Если не создать это. mt025 5 лет назад 0
Конечно, он существует ... Fidel 5 лет назад 0

3 ответа на вопрос

3
William Pursell

Вы назначаете PROMPT_COMMAND неправильно. Когда ты пишешь

PROMPT_COMMAND=$(history -a; $PROMPT_COMMAND) 

Вы запускаете 'history -a' (которая не производит вывод), а затем запускаете $ PROMPT_COMMAND (который во время ваших сценариев запуска может быть пустым) и назначаете вывод этих двух команд (пустую строку) в PROMPT_COMMAND. То, что вы хотите, это просто:

PROMPT_COMMAND='history -a' 

Если вы хотите добавить его к уже существующей команде, выполните

PROMPT_COMMAND+="history -a$$PROMPT_COMMAND" 
Спасибо, но все еще не работает. Я пробовал обе вещи. Файл сохраняется только при запуске exit. Fidel 5 лет назад 0
Каково текущее значение PROMPT_COMMAND? Если это `history -a`, что произойдет, если вы` tail $ HISTFILE`? Обратите внимание, что PROMPT_COMMAND не запускается до тех пор, пока ваша команда не завершится, поэтому вы можете поместить `history -a` в ловушку отладки, которая запускается перед командой. William Pursell 5 лет назад 0
Значение PROMPT_COMMAND - это история -a. $ HISTFILE не существует (как я говорил с самого начала, он создается только при запуске exit), поэтому tail этой переменной возвращает ошибку «not open». Можете ли вы объяснить «отладочную ловушку» лучше? Fidel 5 лет назад 0
Вы можете попробовать `PROMPT_COMMAND = 'touch $ HISTFILE; history -a'` Или `trap 'touch $ HISTFILE; история -a 'DEBUG` William Pursell 5 лет назад 0
Так же. С любым из них результат тот же. Единственное отличие состоит в том, что теперь, когда я запускаю новый терминал, существует $ HISTFILE, но ничего не пишется, пока я не выйду. Fidel 5 лет назад 0
Значит, я предполагаю, что это невозможно? Fidel 5 лет назад 0
Это совсем не невозможно. Я делю свою историю на отдельные файлы на основе pid оболочки, используя `history -a` в ловушке отладки, а затем объединяю ее в общий файл с информацией о состоянии, текущим рабочим каталогом и некоторыми другими метаданными в PROMPT_COMMAND , Вам нужно сделать больше отладки. Вы пытались напечатать какую-либо диагностическую информацию во время PROMPT_COMMAND? William Pursell 5 лет назад 0
Какую версию Bash вы используете? William Pursell 5 лет назад 0
Спасибо, но я на самом деле не знаю, горячо сделать больше отладки. Основная версия: 4.2.1 (2) (x86_64-redhat-linux-gnu) Fidel 5 лет назад 0
1
Sherwood Botsford

Отвечая на намерение, а не на буквальный вопрос:

Посмотрите на использование сценария. Это даст вам команды и их вывод. Обратите внимание, что это не панацея, так как любые команды, которые используют позиционирование курсора, трудно расшифровать позже.

Name script - сделать машинописный текст терминальной сессии

Сценарий синопсиса [-a] [-c КОМАНДА] [-f] [-q] [-t] [файл]

Описание Script делает набор текста всего, что напечатано на вашем терминале. Это полезно для студентов, которым нужна бумажная запись интерактивного сеанса в качестве доказательства задания, поскольку файл машинописного текста можно распечатать позже с помощью lpr (1).

Если указан файл аргумента, скрипт сохраняет весь диалог в файл. Если имя файла не указано, машинописный текст сохраняется в машинописном тексте.

Опции:

 -a' Append the output to file or typescript, retaining the priorcontents. 

-c КОМАНДА Запускайте КОМАНДУ, а не интерактивную оболочку. Это позволяет сценарию легко захватывать выходные данные программы, которая ведет себя по-разному, когда ее стандартный вывод не является tty. -f 'Сбрасывать вывод после каждой записи. Это хорошо для телеоперации: один человек делает mkfifo foo; скрипт -f foo 'и другой могут контролировать в реальном времени, что делается с помощью' cat foo '.

-q 'Молчи.

-t 'Вывести данные синхронизации в стандартную ошибку. Эти данные содержат два поля, разделенные пробелом. Первое поле показывает, сколько времени прошло с момента предыдущего вывода. Второе поле показывает, сколько символов было выведено на этот раз. Эта информация может быть использована для воспроизведения шрифтов с реалистичными задержками при наборе текста и выводе.

Скрипт завершается, когда разветвленная оболочка выходит (control-D для выхода из оболочки Bourne (sh (1)), и exit, logout или control-d (если ignoreeof не установлено) для C-оболочки, csh (1) ).

Некоторые интерактивные команды, такие как vi (1), создают мусор в файле машинописного текста. Скрипт лучше всего работает с командами, которые не манипулируют экраном, результаты предназначены для эмуляции печатного терминала. ...

Поиск "человек сценарий" в Google. Если у вас есть конкретная ОС, включите это. Это версия для Linux, но существуют почти идентичные версии для * BSD, Mac. Вероятно, порты Windows тоже там.

Не очень полезно, но спасибо за усилия. Я просто хочу историю команд, которые я запускаю, а не результаты. И я не хочу вводить больше уровней сложности в то, что должно быть легко. Fidel 5 лет назад 0
1
Fidel

По какой-то причине, которую я не могу понять, это работает:

export HISTFILE_NEW="$HOME/HISTORIES/bash_history_$(basename $(tty))_$(date '+%Y-%m-%d_%H-%M-%S_%Z')" export HISTCONTROL=ignoreboth export HISTFILESIZE=10000 export HISTSIZE=10000 shopt -s histappend PROMPT_COMMAND="history -w $HISTFILE_NEW; $PROMPT_COMMAND" 

Хотя это не

export HISTFILE="$HOME/HISTORIES/bash_history_$(basename $(tty))_$(date '+%Y-%m-%d_%H-%M-%S_%Z')" export HISTCONTROL=ignoreboth export HISTFILESIZE=10000 export HISTSIZE=10000 shopt -s histappend PROMPT_COMMAND="history -a; $PROMPT_COMMAND" 

Конечно, первое решение медленнее, чем теоретически хорошее (второе), потому что вся история сохраняется каждый раз, когда пишется новая команда.

Поэтому, если кто-нибудь знает, ПОЧЕМУ это так и как это можно решить, я был бы очень признателен.

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