Вопрос или проблема
В течение последнего года или двух я активно использовал sqlite3 для веб-разработки. Постоянно я сталкивался с проблемой, когда внезапно история команд переставала работать (при нажатии стрелки вверх вы получаете историю команд, как и в bash).
К вашему сведению
Я использую Ubuntu 22.04.3 LTS (6.5.0-21-generic) и .NET Core 8.0.200
Что я пробовал
Я не смог это выяснить.
- Я examined examined файл
~/.sqlite_history
, и он выглядел нормально. - Проверил переменную окружения
$SQLITE_HISTORY
, но у меня её нет, и всё работает (подробнее ниже) - Обновил до последней версии sqlite3 (3.45.1 2024-01-30)
- Я исследовал довольно много проблем, связанных с этим, но всё равно не смог выяснить, почему вдруг история не работает.
Правка – Попробовал консольное приложение, также вызывает проблему
- Открыл новый терминал
- Открыл базу данных sqlite3 и протестировал команду истории — она работает.
- Вышел из sqlite3 обратно в командную строку (тот же терминал)
- Запустил консольное приложение .NET Core, которое выводит “Hello, World” в консоль и завершает работу. (начал с dotnet run)
- Открыл ту же базу данных sqlite3 из шага 2. Попробовал историю. История больше не работает в этом окне терминала.
Наконец-то обнаружил, что вызывает проблему
Я наконец выяснил, почему история sqlite3 не работает.
Однако я не понимаю, почему это вызывает проблему.
Чтобы воспроизвести проблему, мне нужно:
- запустить веб-приложение .NET Core Пример: (
$ dotnet run --project myWebApi
) - остановить веб-API (CTRL-C)
- запустить sqlite3, чтобы проверить свою базу данных — на этом этапе у меня нет истории (нажатие стрелки вверх не дает результатов)
Подсказка к проблеме
Если я открою новый терминал и запущу sqlite3, то у меня снова будет история.
Приложение dotnet core работает от моего имени, и я не думаю, что там происходит что-то странное, но я не уверен.
Вы знаете, почему это происходит?
Решение оказалось следующим:
$ tput init
или в командной строке sqlite
> .shell tput init
У терминалов есть несколько различных наборов последовательностей клавиш для стрелок. Обычно Вверх вводит последовательность ESC [ A
, но есть “режим клавиш приложения”, в котором та же клавиша вводит ESC O A
вместо этого.
По каким-то причинам как Wine, так и dotnet имеют тенденцию активировать этот режим — возможно, в качестве непреднамеренной части их “консольных” абстракций — и затем забывают деактивировать его при выходе.
(Обычно tput smkx
↔ tput rmkx
должны (де)активировать этот режим.)
Последняя последовательность клавиш, если я не ошибаюсь, не просто “стрелка вверх, в режиме приложения” — есть другой терминал, который случайно использует ту же последовательность для “Ctrl-стрелка вверх” или что-то в этом роде. Поэтому по какой-то причине библиотека ввода readline, используемая Bash и различными другими программами (включая sqlite), имеет эту последовательность, связанную с другим действием, чем обычное “стрелка вверх / предыдущая история”.
Ответ или решение
Проблема с отсутствием истории команд в SQLite3 после запуска .NET Core приложения может быть следствием изменения режима обработки клавиш терминала. В вашем случае, когда вы используете SQLite3 после работы с .NET Core, история команд (доступная с помощью клавиши стрелки "вверх") перестает работать. Давайте проанализируем эту ситуацию детально.
Причины проблемы
-
Режимы клавиатуры терминала: Когда вы запускаете .NET Core приложение, терминал может переключить обработку клавиш в "режим приложения". Это может произойти из-за особенностей реализации терминала, используемого в Linux, который интерпретирует ввод клавиш по-разному. В "режиме приложения" клавиша "вверх" может отправлять последовательность
ESC O A
, в то время как в стандартном режиме ожидаетсяESC [ A
. Это изменение является причиной того, почему SQLite3 не распознает вашу историю команд. -
Неполное возвращение в стандартный режим: Важно отметить, что после выхода из .NET Core приложения режим приложения не восстанавливается автоматически, что приводит к неожиданному поведению в последующих запусках SQLite3.
Решения
Вы уже обнаружили два возможных подхода для решения этой проблемы:
-
Инициализация терминала с помощью
tput
: Командаtput init
или
.shell tput init
сбрасывает настройки терминала в исходное состояние, что помогает устранить проблему с обработкой клавиш.
-
Использование
tput smkx
иtput rmkx
: Эти команды активируют и деактивируют режим приложения для клавиш соответственно. Вы можете использовать следующие команды:tput smkx # Включить режим приложения tput rmkx # Выключить режим приложения
Заключение
Таким образом, проблема с историей команд SQLite3 после работы с .NET Core связана с изменением режима обработки клавиш в терминале, вызванным работой приложений, работающих в .NET. Рекомендуется использовать команды tput init
или контролировать режимы клавиш с помощью tput smkx
и tput rmkx
, чтобы избежать подобных проблем в будущем.
Для улучшения работы с терминалом, вы также можете убедиться, что все ваши переменные окружения правильно настроены, однако, в вашем случае это не привело к проблеме, так как у вас отсутствует переменная $SQLITE_HISTORY
.
Если у вас будут дополнительные вопросы или потребуется поддержка, не стесняйтесь обращаться за помощью.