Как я могу использовать эмулятор терминала в качестве эффективного лаунчера приложений?

Вопрос или проблема

Проблема

На протяжении своих лет использования 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, у меня есть мощное автозавершение для путей, имен команд и аргументов.
  • Псевдонимы: Некоторые программы легче и быстрее запускать через мои пользовательские псевдонимы.

Моя цель

Я хочу использовать эмулятор терминала в качестве простого загрузчика приложений. Вот как это должно работать:

  1. Нажать сочетание клавиш для запуска терминала (например, kitty).
  2. Ввести команду (например, firefox).
  3. Нажать <Enter>. Терминал должен:
    • Запустить команду.
    • Сразу закрыться.
    • Оставить запущенное приложение работающим.

Например, ввод firefox должен работать как выполнение firefox & disown & exit или nohup firefox > /dev/null 2>&1 & exit. Ввод & disown & exit после команды достигает желаемого эффекта, но, конечно, я не хочу вручную добавлять & disown & exit каждый раз.

Примечание: это не поглощение окна. Я не хочу, чтобы окно терминала оставалось открытым после закрытия приложения; мне нужен терминал только для ввода.


Что я пробовал

  1. Использование read:
    Запуск kitty с этой командой:

    kitty -e bash -i -c 'read -e -p "Command: " cmd; eval "$cmd"'
    

    Этот подход не сработал, потому что ввод через read обходил некоторые функции оболочки, которые я хочу, такие как автозавершение и история команд.

  2. Автоматизация с помощью вторичного сочетания клавиш:
    Ввод команды и использование другого сочетания клавиш (например, Super+<Enter>) для добавления и выполнения & disown & exit<Enter> с помощью инструмента, такого как wtype.
    Это довольно обходной путь, но я бы согласился на это, если бы это работало. К сожалению, это не работает: нажатие модификаторной клавиши, такой как Super, вызывает нежелательное поведение: каждый символ в строке (& disown & exit<Enter>) отправляется с модификатором, вызывая срабатывание сочетаний клавиш вместо интерпретации как текста.


Заключение

Как я могу это достичь? Я хочу решение, которое позволит мне быстро запускать приложения, используя все функции интерактивной оболочки bash.

Я бы действовал в этом порядке мыслей:

  1. Измените свою оболочку, чтобы “подключить” выполнение команд
  2. в этом хуке вы не выполняете саму команду, а
    1. запускаете программу в контексте вашей графической оболочки (так что никаких disown или nohup)
    2. выходите из оболочки (тем самым закрывая окно).

Установка этого хука может быть выполнена в пользовательском файле 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. Цели

Наша конечная цель — создать в терминальном эмуляторе простой интерфейс для запуска приложений, который будет:

  1. Запускаться по комбинированной клавише.
  2. Позволять вводить название команды.
  3. Закрывать терминал сразу после запуска команды.

Например, при вводе 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 еще более комфортной.

Оцените материал
Добавить комментарий

Капча загружается...