Lançar um emulador de terminal sem saber quais estão instalados

Lançar um emulador de terminal sem saber quais estão instalados

Preciso escrever um script que inicie um emulador de terminal e execute um comando específico nele. Como não sei quais emuladores de terminal foram instalados no sistema de destino, como posso descobrir quais emuladores de terminal foram instalados?

eu olheieste tópico. No entanto, não estou muito inclinado a fazer uma verificação codificada e estou procurando uma solução genérica.

Eu descobri issomuitotruque sujo, mas não tenho certeza de como isso funcionaria:

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

Existe uma solução genérica fácil que talvez esteja faltando? Ou não tenho outra maneira senão vasculhar os binários em busca de dicas ou usar uma lista codificada?

Responder1

Suas heurísticas são muito ruins. Aqui está o que eles encontraram em uma máquina Debian wheezy minha (marquei manualmente os acertos corretos com um +).

/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                 +

Se você escolher a primeira correspondência alfabética, será um calibrador de cores.

Aqui está a lista de alternativas para x-terminal-emulator, que é a resposta correta (no que diz respeito a programas gerenciados por distribuição) nesta máquina 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

Você está encontrando 7 em 15 (levando em consideração os caprichos dos nomes), o que não é uma taxa de acerto muito boa.

Você poderia tentar refinar sua heurística, mas é um jogo sem fim. O mínimo seria reter apenas executáveis ​​​​que se vinculem a algumas bibliotecas X11 e chamem alguma função ou utilitário de terminal mestre como getptor grantpt, mas isso também encontrará muitos aspectos positivos espúrios e perderá executáveis ​​​​onde a chamada estiver em uma biblioteca ( como konsole). E isso fará falta aos executáveis ​​de código nativo que são acessados ​​por meio de um wrapper de shell (há vários na minha lista).

Detectar se um programa é um emulador de terminal X a partir do conteúdo executável é inútil.

Detectar programas pelo nome é uma heurística muito melhor.

Observe também que diferentes programas têm uma sintaxe de linha de comando diferente. A maioria deles aceita e , mas eles têm regras de análise diferentes para (passar por um shell ou não, receber vários argumentos ou não), então você deve passar um único parâmetro depois de , não contendo nenhum caractere especial do shell.-T TITLE-e COMMAND-e-e

No Debian e derivados,x-terminal-emulatoré garantido ser um emulador de terminal X que suporta -Tand -e, que -eusa todos os parâmetros de linha de comando subsequentes como um comando e seu argumento e não faz expansão de shell neles. Como alguns emuladores se comportam de maneira diferente, x-terminal-emulatoràs vezes é um wrapper que adota uma sintaxe mais parecida com o xterm ( gnome-terminal.wrappere xfce4-terminal.wrappersão dois exemplos disso).

Não conheço nada parecido com isso em outras variantes do Unix. Para qualquer coisa como portabilidade, uma lista codificada de nomes de programas é sua melhor aposta.

Além disso, detectar emuladores de terminal instalados não lhe dará nenhuma ideia sobre as preferências do usuário. Por exemplo, se eu uso o Gnome, provavelmente não quero que seu aplicativo inicie o Konsole — a menos que eu prefira o Konsole, mas como você saberia disso?

O padrão de fato para as preferências do usuário é viaFreeDesktop.orgespecificações. Freedesktop publica umxdg-utilspacote que contém programas comoxdg-openpara abrir um documento no aplicativo adequado,xdg-emailpara iniciar o aplicativo de composição de e-mail preferido do usuário e, mais especificamentexdg-terminalpara abrir o emulador de terminal preferido do usuário.

Isso seria xdg-terminala coisa certa a ser usada, e você deve usá-la se estiver lá. Infelizmente, xdg-terminalnão está disponível em todos os lugares; por exemplo, o Debian não o envia (é umbug de longa inatividade). Além dissoxdg-terminalpermite um único argumento de comando e não é consistente sobre o tipo de expansão que esse argumento sofre.

Faça o que fizer, certifique-se de fornecer uma maneira fácil para o chamador especificar uma preferência. Even xdg-terminalnem sempre acerta.

Portanto, sua melhor estratégia é:

  1. se o usuário especificou uma preferência, use-a
  2. senão tentexdg-terminal
  3. senão tentex-terminal-emulator
  4. senão tente uma lista codificada

Responder2

No Debian e derivados (Ubuntu, Mint, …), x-terminal-emulatorsempre será iniciado o terminal gráfico padrão do administrador.
Você pode até incluir algo assim para determinar se é uma sessão gráfica:

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

informação relacionada