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 getpt
or 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 -T
and -e
, que -e
usa 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.wrapper
e xfce4-terminal.wrapper
sã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-utils
pacote que contém programas comoxdg-open
para abrir um documento no aplicativo adequado,xdg-email
para iniciar o aplicativo de composição de e-mail preferido do usuário e, mais especificamentexdg-terminal
para abrir o emulador de terminal preferido do usuário.
Isso seria xdg-terminal
a coisa certa a ser usada, e você deve usá-la se estiver lá. Infelizmente, xdg-terminal
não está disponível em todos os lugares; por exemplo, o Debian não o envia (é umbug de longa inatividade). Além dissoxdg-terminal
permite 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-terminal
nem sempre acerta.
Portanto, sua melhor estratégia é:
- se o usuário especificou uma preferência, use-a
- senão tente
xdg-terminal
- senão tente
x-terminal-emulator
- senão tente uma lista codificada
Responder2
No Debian e derivados (Ubuntu, Mint, …), x-terminal-emulator
sempre 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