Lanzar un emulador de terminal sin saber cuáles están instalados

Lanzar un emulador de terminal sin saber cuáles están instalados

Necesito escribir un script que inicie un emulador de terminal y ejecute un comando particular en él. Como no sé qué emuladores de terminal se han instalado en el sistema de destino, ¿cómo puedo saber qué emuladores de terminal se han instalado?

he miradoeste hilo. Sin embargo, no estoy muy dispuesto a realizar una verificación codificada y estoy buscando una solución genérica.

Se me ocurrió estomuytruco sucio, pero realmente no estoy seguro de cómo le iría a esto:

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 una solución genérica sencilla que quizás me esté perdiendo? ¿O no tengo otra forma que buscar pistas en archivos binarios o utilizar una lista codificada?

Respuesta1

Tus heurísticas son bastante malas. Esto es lo que encuentran en una de mis máquinas Debian wheezy (he marcado manualmente los resultados correctos con un +).

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

Si elige la primera coincidencia alfabética, es un calibrador de color.

Aquí está la lista de alternativas para x-terminal-emulator, que es la respuesta correcta (en lo que respecta a programas administrados por distribución) en esta 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

Estás encontrando 7 de 15 (teniendo en cuenta los caprichos de los nombres), lo que no es una tasa de aciertos muy buena.

Podrías intentar perfeccionar tu heurística, pero es un juego sin fin. Lo mínimo sería retener solo los ejecutables que se vinculen con algunas bibliotecas X11 y llamen a alguna función o utilidad del terminal maestro como getpto grantpt, pero eso seguramente también encontrará muchos positivos falsos y omitirá ejecutables donde la llamada está en una biblioteca ( como konsole). Y esto omitirá los ejecutables de código nativo a los que se accede a través de un contenedor de shell (hay varios en mi lista).

Detectar si un programa es un emulador de terminal X a partir del contenido ejecutable es inútil.

Detectar programas por su nombre es una heurística mucho mejor.

Tenga en cuenta también que diferentes programas tienen una sintaxis de línea de comando diferente. La mayoría de ellos aceptan y , pero tienen diferentes reglas de análisis para (pasar por un shell o no, tomar múltiples argumentos o no), por lo que debe pasar un único parámetro después de , que no contenga ningún carácter especial del shell.-T TITLE-e COMMAND-e-e

En Debian y derivados,x-terminal-emulatorSe garantiza que será un emulador de terminal X que admita -Ty -e, de modo que -eutilice todos los parámetros de línea de comando posteriores como un comando y su argumento y no expanda el shell en ellos. Debido a que algunos emuladores se comportan de manera diferente, x-terminal-emulatora veces hay un contenedor que toma una sintaxis más parecida a xterm ( gnome-terminal.wrappery xfce4-terminal.wrapperson dos ejemplos de esto).

No conozco nada parecido en otras variantes de Unix. Para cualquier cosa parecida a la portabilidad, la mejor opción es una lista codificada de nombres de programas.

Además, detectar emuladores de terminal instalados no te dará ninguna idea sobre las preferencias del usuario. Por ejemplo, si uso Gnome, probablemente no quiera que su aplicación inicie Konsole, a menos que prefiera Konsole, pero ¿cómo puede saberlo?

El estándar de facto para las preferencias del usuario es a través deFreeDesktop.orgespecificaciones. Freedesktop publica unxdg-utilspaquete que contiene programas comoxdg-openpara abrir un documento en la aplicación adecuada,xdg-emailpara iniciar la aplicación de redacción de correo electrónico preferida del usuario, y más al puntoxdg-terminalpara abrir el emulador de terminal preferido del usuario.

Esto sería xdg-terminallo correcto y deberías usarlo si está allí. Desafortunadamente, xdg-terminalno está disponible en todas partes; por ejemplo, Debian no lo incluye (es unerror de inactividad prolongada). Ademásxdg-terminalpermite un único argumento de comando y no es coherente sobre qué tipo de expansión sufre este argumento.

Hagas lo que hagas, asegúrate de proporcionar una manera fácil para que la persona que llama especifique una preferencia. Incluso xdg-terminalno siempre lo hace bien.

Por tanto, tu mejor estrategia es:

  1. si el usuario ha especificado una preferencia, úsela
  2. si no, inténtaloxdg-terminal
  3. si no, inténtalox-terminal-emulator
  4. de lo contrario, pruebe con una lista codificada

Respuesta2

En Debian y derivados (Ubuntu, Mint,…), x-terminal-emulatorsiempre se iniciará la terminal gráfica predeterminada del administrador.
Incluso puedes incluir algo como esto para determinar si es una sesión gráfica:

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

información relacionada