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 getpt
o 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-emulator
Se garantiza que será un emulador de terminal X que admita -T
y -e
, de modo que -e
utilice 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-emulator
a veces hay un contenedor que toma una sintaxis más parecida a xterm ( gnome-terminal.wrapper
y xfce4-terminal.wrapper
son 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-utils
paquete que contiene programas comoxdg-open
para abrir un documento en la aplicación adecuada,xdg-email
para iniciar la aplicación de redacción de correo electrónico preferida del usuario, y más al puntoxdg-terminal
para abrir el emulador de terminal preferido del usuario.
Esto sería xdg-terminal
lo correcto y deberías usarlo si está allí. Desafortunadamente, xdg-terminal
no está disponible en todas partes; por ejemplo, Debian no lo incluye (es unerror de inactividad prolongada). Ademásxdg-terminal
permite 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-terminal
no siempre lo hace bien.
Por tanto, tu mejor estrategia es:
- si el usuario ha especificado una preferencia, úsela
- si no, inténtalo
xdg-terminal
- si no, inténtalo
x-terminal-emulator
- de lo contrario, pruebe con una lista codificada
Respuesta2
En Debian y derivados (Ubuntu, Mint,…), x-terminal-emulator
siempre 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