Запуск эмулятора терминала без знания того, какие из них установлены

Запуск эмулятора терминала без знания того, какие из них установлены

Мне нужно написать скрипт, который запустит эмулятор терминала и выполнит в нем определенную команду. Поскольку я не знаю, какие эмуляторы терминала установлены в целевой системе, как мне узнать, какие эмуляторы терминала установлены?

Я посмотрел наэта тема. Однако я не очень склонен делать жестко запрограммированную проверку и ищу универсальное решение.

Я придумал этооченьГрязный хак, но я действительно не уверен, что из этого получится:

termdetect:

#!/bin/bash

IFS=:
for i in $PATH; do
  find "$i" -type f -exec isterminal {} \;
done

isterminal:

#!/bin/bash

if [[ ! -z "$1" ]]; then
  if [[ "$(head -c 4 "$1")" == $'\x7fELF' ]]; then
    if ! grep editor "$1" > /dev/null; then
      if grep -E '(vte_terminal_|libutempter|rxvt_)' "$1" > /dev/null; then
        echo "$1"
      fi
    fi
  fi
fi

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

решение1

Ваши эвристики довольно плохи. Вот что они находят на моей машине с Debian wheezy (я вручную отметил правильные совпадения с помощью +).

/usr/bin/gcm-calibrate
/usr/bin/gnome-terminal        +
/usr/bin/mosh-client   
/usr/bin/mosh-server
/usr/bin/mrxvt                 +
/usr/bin/mrxvt-full            +
/usr/bin/roxterm               +
/usr/bin/rxvt-unicode          +
/usr/bin/urxvt                 +
/usr/bin/urxvtd
/usr/bin/vinagre
/usr/bin/x-terminal-emulator   +
/usr/bin/xfce4-terminal        +
/usr/bin/xterm                 +

Если вы выбрали первое буквенное совпадение, это калибратор цвета.

Вот список альтернатив для x-terminal-emulator, который является правильным ответом (в отношении программ, управляемых дистрибутивом) на этой машине Debian:

/usr/bin/Eterm
/usr/bin/gnome-terminal.wrapper
/usr/bin/koi8rxterm
/usr/bin/konsole
/usr/bin/lxterm
/usr/bin/mlterm
/usr/bin/mrxvt-full
/usr/bin/roxterm
/usr/bin/rxvt-xpm
/usr/bin/rxvt-xterm
/usr/bin/urxvt
/usr/bin/uxterm
/usr/bin/xfce4-terminal.wrapper
/usr/bin/xterm
/usr/bin/xvt

Вы находите 7 из 15 (с учетом неточностей названий), что не очень хороший показатель совпадений.

Вы можете попытаться усовершенствовать свою эвристику, но это бесконечная игра. Минимальным вариантом будет сохранение только исполняемых файлов, которые и связаны с некоторыми библиотеками X11, и вызывают некоторые функции или утилиты главного терминала, например, getptили grantpt, но это также обязательно приведет к обнаружению множества ложных срабатываний и пропуску исполняемых файлов, где вызов находится в библиотеке (например, konsole). И это пропустит исполняемые файлы нативного кода, доступ к которым осуществляется через оболочку оболочки (в моем списке их несколько).

Определить, является ли программа эмулятором X-терминала, по исполняемому содержимому — безнадежная задача.

Обнаружение программ по имени — гораздо лучший эвристический метод.

Обратите внимание, что разные программы имеют разный синтаксис командной строки. Большинство из них принимают и , но у них разные правила разбора (проход через оболочку или нет, прием нескольких аргументов или нет), поэтому вам следует передать один параметр после , не содержащий никаких специальных символов оболочки.-T TITLE-e COMMAND-e-e

В Debian и производных,x-terminal-emulatorгарантированно является эмулятором X-терминала, который поддерживает -Tи -e, так что -eиспользует все последующие параметры командной строки как команду и ее аргумент и не выполняет расширение оболочки для них. Поскольку некоторые эмуляторы ведут себя по-разному, x-terminal-emulatorиногда является оболочкой, которая принимает синтаксис, более похожий на xterm ( gnome-terminal.wrapperи xfce4-terminal.wrapperявляются двумя примерами этого).

Я не знаю ничего подобного в других вариантах unix. Для чего-то вроде переносимости, жестко закодированный список имен программ — ваш лучший выбор.

Более того, обнаружение установленных эмуляторов терминала не даст вам никаких сведений о предпочтениях пользователя. Например, если я использую Gnome, я, вероятно, не хочу, чтобы ваше приложение запускало Konsole — если только я случайно не предпочитаю Konsole, но откуда вы это знаете?

Фактическим стандартом для пользовательских предпочтений являетсяFreeDesktop.orgХарактеристики. Freedesktop публикуетxdg-utilsпакет, который содержит такие программы, какxdg-openоткрыть документ в соответствующем приложении,xdg-emailдля запуска предпочитаемого пользователем приложения для составления электронных писем и т. д.xdg-terminalчтобы открыть предпочитаемый пользователем эмулятор терминала.

Это было бы xdg-terminalправильным решением, и вам следует использовать его, если он есть. К сожалению, xdg-terminalон не везде доступен; например, Debian не поставляет его (этоошибка длительного простоя). Более тогоxdg-terminalдопускает один аргумент команды и не является последовательным относительно того, какой тип расширения этот аргумент претерпевает.

Что бы вы ни делали, убедитесь, что вы предоставляете вызывающему абоненту простой способ указать предпочтения. Даже xdg-terminalне всегда делает это правильно.

Таким образом, ваша лучшая стратегия:

  1. если пользователь указал предпочтение, используйте его
  2. еще попробуйxdg-terminal
  3. еще попробуйx-terminal-emulator
  4. или попробуйте жестко закодированный список

решение2

В Debian и производных (Ubuntu, Mint, …) x-terminal-emulatorвсегда будет запускаться графический терминал администратора по умолчанию.
Вы даже можете включить что-то вроде этого, чтобы определить, является ли это графическим сеансом:

if [ -z "$XAUTHORITY" ]
then 
 echo "Failed to launch terminal emulator! This is not a graphical session."
else
 x-terminal-emulator
fi

Связанный контент