- Вопрос или проблема
- Проблема
- Моя цель
- Что я пробовал
- Заключение
- легкий на zsh
- bash: возможно, но немного сложнее, я думаю
- Ответ или решение
- Как использовать терминальный эмулятор в качестве эффективного лаунчера приложений
- 1. Зачем использоватьTerminal?
- 2. Цели
- 3. Основные шаги
- 4. Тестирование и настройка
- 5. Заключение
Вопрос или проблема
Проблема
На протяжении своих лет использования Linux я пользовался различными загрузчиками приложений, такими как rofi
, albert
, wofi
, dmenu
и другими. Несмотря на свои плюсы и минусы, одна вещь всегда меня беспокоила: это не оболочка bash.
Почему это важно? Мне действительно нравятся некоторые функции bash, такие как:
- Сочетания клавиш GNU Readline: Навигация или редактирование текста с помощью
Ctrl+A
(начало строки),Ctrl+E
(конец),Ctrl+K
(удалить текст),Ctrl+Y
(вставить),Meta+Y
(вставить из истории) и многое другое. - История команд: Использование
~/.bash_history
для поиска с помощьюCtrl+R
/Ctrl+S
, или навигация по командам с помощьюCtrl+P
/Ctrl+N
. - Автозавершение: С такими инструментами, как
bash-completion
иbash-complete-alias
, у меня есть мощное автозавершение для путей, имен команд и аргументов. - Псевдонимы: Некоторые программы легче и быстрее запускать через мои пользовательские псевдонимы.
Моя цель
Я хочу использовать эмулятор терминала в качестве простого загрузчика приложений. Вот как это должно работать:
- Нажать сочетание клавиш для запуска терминала (например,
kitty
). - Ввести команду (например,
firefox
). - Нажать
<Enter>
. Терминал должен:- Запустить команду.
- Сразу закрыться.
- Оставить запущенное приложение работающим.
Например, ввод firefox
должен работать как выполнение firefox & disown & exit
или nohup firefox > /dev/null 2>&1 & exit
. Ввод & disown & exit
после команды достигает желаемого эффекта, но, конечно, я не хочу вручную добавлять & disown & exit
каждый раз.
Примечание: это не поглощение окна. Я не хочу, чтобы окно терминала оставалось открытым после закрытия приложения; мне нужен терминал только для ввода.
Что я пробовал
-
Использование
read
:
Запускkitty
с этой командой:kitty -e bash -i -c 'read -e -p "Command: " cmd; eval "$cmd"'
Этот подход не сработал, потому что ввод через
read
обходил некоторые функции оболочки, которые я хочу, такие как автозавершение и история команд. -
Автоматизация с помощью вторичного сочетания клавиш:
Ввод команды и использование другого сочетания клавиш (например,Super+<Enter>
) для добавления и выполнения& disown & exit<Enter>
с помощью инструмента, такого какwtype
.
Это довольно обходной путь, но я бы согласился на это, если бы это работало. К сожалению, это не работает: нажатие модификаторной клавиши, такой какSuper
, вызывает нежелательное поведение: каждый символ в строке (& disown & exit<Enter>
) отправляется с модификатором, вызывая срабатывание сочетаний клавиш вместо интерпретации как текста.
Заключение
Как я могу это достичь? Я хочу решение, которое позволит мне быстро запускать приложения, используя все функции интерактивной оболочки bash.
Я бы действовал в этом порядке мыслей:
- Измените свою оболочку, чтобы “подключить” выполнение команд
- в этом хуке вы не выполняете саму команду, а
- запускаете программу в контексте вашей графической оболочки (так что никаких
disown
илиnohup
) - выходите из оболочки (тем самым закрывая окно).
- запускаете программу в контексте вашей графической оболочки (так что никаких
Установка этого хука может быть выполнена в пользовательском файле RC, который вы укажете для загрузки.
Сам хук:
легкий на zsh
(Я бы на самом деле рекомендовал zsh
здесь), просто реализуйте preexec
; добавьте что-то похожее на следующее в ваш ~/.zshrc
preexec() {
# /--------------------+--- если мы не в режиме "только более гламурной командной строки", пропускаем
# | |
# | |
# | | /-- запустить с использованием "systemd-run" в контексте пользователя
# | | | /--- остаться в том же рабочем каталоге
# | | | |
# | | | |
# | | | | /-- ${=VARIABLE} разворачивает переменную
# | | | | | содержащую пробелы, в список
# | | | | | отдельных аргументов
# | | | | |
# | | | | | /-- если все прошло хорошо, выходим!
# | | | | | |
# vvvvvvvvvvvvvvvvvvvvvv v v v v
[[ -v PROMPT_AND_EXIT ]] && systemd-run --user -d ${=2} && exit
# ^
# |
# `preexec()` получает три аргумента: 1. это строка, введенная пользователем, 2. "предварительно развернутая",
# и 3. аргумент - это полностью развернутая строка (после псевдонимов и функций).
# Этот третий аргумент, $2, мы и используем.
}
и запускайте свой терминал как kitty -e env PROMPT_AND_EXIT=1 zsh
.
bash
: возможно, но немного сложнее, я думаю
я на самом деле не пробовал это, но я уверен, что вы можете “собрать” похожее поведение на bash
, как вы получаете с preexec
на zsh
. Быстрый обзор исходного кода bash
не показывает ничего, что похоже на zsh
‘s preexec()
, но вы, вероятно, можете реализовать хук DEBUG something_invoke_exec
. Это, похоже, потребует больше работы (и потенциально может снизить производительность), но это позволит вам концептуально сделать то же самое, что я показал для zsh
. Однако я этого не пробовал, из-за ограниченного времени (и ограниченного использования – я считаю, что редактирование командной строки в bash
гораздо менее развито, чем в zsh
, и поэтому предпочитаю последнюю в интерактивном использовании). Вам стоит это исследовать!
Ответ или решение
Как использовать терминальный эмулятор в качестве эффективного лаунчера приложений
Современные пользователи Linux часто стремятся оптимизировать свои рабочие процессы, и лаунчеры приложений играют в этом важную роль. Однако, несмотря на множество доступных инструментов, таких как rofi
, albert
, wofi
и dmenu
, многие пользователи жалуются на то, что они не могут воспользоваться всеми преимуществами, которые предоставляет оболочка Bash, такими как доступ к истории команд и поддержка завершения команд. В этой статье мы обсудим, как вы можете использовать терминальный эмулятор, например kitty
, как эффективный лаунчер приложений, при этом сохраняя преимущества интерпретатора команд.
1. Зачем использоватьTerminal?
Использование терминала в качестве лаунчера позволяет:
- Использовать сочетания клавиш GNU Readline: Такие как
Ctrl+A
для начала строки иCtrl+E
для конца строки. - Воспользоваться историей команд: С помощью
Ctrl+R
можно легко находить ранее введенные команды. - Автозавершение: С помощью
bash-completion
оказывается доступ к мощной функции автозавершения для путей, имен команд и аргументов. - Алиасы: Упрощение запуска часто используемых команд.
2. Цели
Наша конечная цель — создать в терминальном эмуляторе простой интерфейс для запуска приложений, который будет:
- Запускаться по комбинированной клавише.
- Позволять вводить название команды.
- Закрывать терминал сразу после запуска команды.
Например, при вводе firefox
, терминал должен выполнять firefox & disown & exit
, но мы не хотим каждый раз вручную добавлять & disown & exit
к командам.
3. Основные шаги
Чтобы достичь этой цели, мы можем воспользоваться хуком в оболочке. Для этого выполним следующие действия:
Для zsh
Рекомендуется использовать zsh
, поскольку он предлагает более простые способы реализации хуков, таких как preexec
. Добавьте следующее в ваш файл ~/.zshrc
:
preexec() {
[[ -v PROMPT_AND_EXIT ]] && systemd-run --user -d ${=2} && exit
}
Получившийся хук будет проверять, установлена ли переменная PROMPT_AND_EXIT
, и если да, то запускать указанную команду в контексте графической сессии пользователя, а затем закрывать терминал.
Запустите терминал следующей командой:
kitty -e env PROMPT_AND_EXIT=1 zsh
Для bash
Реализация в оболочке bash
будет немного сложнее, так как bash
не имеет аналогичного preexec
хука. Однако, вы можете использовать хук DEBUG
, который позволит вам запустить пользовательский код перед выполнением каждой команды.
Примерный код в ~/.bashrc
:
trap '[[ $BASH_COMMAND == *"exit"* ]] || { eval "$BASH_COMMAND & disown & exit"; }' DEBUG
Этот код будет перехватывать команды перед их выполнением, добавляя к ним необходимые элементы.
4. Тестирование и настройка
После того как вы внесли изменения в конфигурационные файлы, откройте новый терминал kitty
и протестируйте ввод команд. Убедитесь, что команды запускаются корректно, а терминал закрывается сразу после выполнения.
5. Заключение
Использование терминального эмулятора как лаунчера приложений — это отличная альтернатива традиционным лаунчерам, которая позволяет сохранять преимущества оболочки Bash. Это решение не только повышает скорость запуска приложений, но и делает работу более эффективной, предлагая такой функционал, как автозавершение и историю команд. С помощью описанных выше методов вы сможете легко настроить свой терминал под свои нужды, что сделает вашу работу с Linux еще более комфортной.