Iniciando um emulador de terminal sem saber quais estão instalados

4

Eu preciso escrever um script que lance 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 encontrar quais emuladores de terminal foram instalados?

Eu consultei esta discussão . No entanto, não estou muito inclinado a fazer uma verificação codificada e estou procurando uma solução genérica.

Eu criei este muito hack 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 eu não tenho outra maneira senão vasculhar binários por dicas ou usar uma lista codificada?

    
por user2064000 18.06.2014 / 11:21

2 respostas

3

Sua heurística é muito ruim. Aqui está o que eles encontram em uma máquina wheezy do Debian (eu manualmente marquei os hits 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 aos 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 de 15 (representando os caprichos dos nomes), o que não é uma boa taxa de acertos.

Você poderia tentar refinar sua heurística, mas é um jogo sem fim. O mínimo seria manter apenas os executáveis que se vinculam a algumas bibliotecas X11 e chamam algumas funções ou utilitários de terminal mestre como getpt ou grantpt , mas isso também causa muitos pontos positivos espúrios, além de ignorar executáveis em que o chamada está em uma biblioteca (como konsole ). E isso vai perder executáveis de código nativo que são acessados através de um invólucro de shell (há vários na minha lista).

Não é possível detectar se um programa é um emulador de terminal X do conteúdo executável.

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

Note também que diferentes programas possuem uma sintaxe de linha de comando diferente. A maioria aceita -T TITLE e -e COMMAND , mas eles têm regras de análise diferentes para -e (passando por um shell ou não, aceitando vários argumentos ou não), portanto você deve passar um único parâmetro após -e , não contendo quaisquer caracteres especiais de shell.

No Debian e seus derivados, x-terminal-emulator é garantido como um emulador de terminal X que suporta -T e -e , tal que -e usa todos os parâmetros de linha de comando subseqüentes 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 usa uma sintaxe mais parecida com o xterm ( gnome-terminal.wrapper e xfce4-terminal.wrapper são dois exemplos disso).

Eu não sei nada disso em outras variantes do unix. Para qualquer coisa como portabilidade, uma lista codificada de nomes de programas é sua melhor aposta.

Além disso, a detecção de emuladores de terminal instalados não dá a você 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ê sabe disso?

O padrão de fato para as preferências do usuário é através das especificações FreeDesktop.org . O Freedesktop publica um pacote xdg-utils que contém programas como xdg-open para abrir um documento na aplicação apropriada, xdg-email para iniciar o aplicativo de composição de e-mail preferido do usuário, e mais até o ponto xdg-terminal para abrir o emulador de terminal preferido do usuário.

Isso tornaria xdg-terminal a coisa certa a ser usada, e você deveria usá-la se estivesse lá. Infelizmente, xdg-terminal não está disponível em todos os lugares; por exemplo, o Debian não o envia (é um erro de longo tempo ). Além disso, xdg-terminal permite um único argumento de comando e não é consistente sobre que tipo de expansão esse argumento sofre.

Não importa o que você faça, forneça uma maneira fácil para o chamador especificar uma preferência. Mesmo xdg-terminal nem sempre acerta.

Assim, sua melhor estratégia é:

  1. se o usuário tiver especificado uma preferência, use-a
  2. else tente xdg-terminal
  3. else tente x-terminal-emulator
  4. else tente uma lista codificada
por 19.06.2014 / 12:17
2

No Debian e nos seus derivados (Ubuntu, Mint,…), x-terminal-emulator sempre ativará 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
    
por 18.06.2014 / 12:20