Ich muss ein Skript schreiben, das einen Terminalemulator startet und darin einen bestimmten Befehl ausführt. Da ich nicht weiß, welche Terminalemulatoren auf dem Zielsystem installiert wurden, wie kann ich herausfinden, welche Terminalemulatoren installiert wurden?
Ich habe mir angesehendieser Thread. Ich bin jedoch nicht wirklich geneigt, eine fest codierte Prüfung durchzuführen, und suche nach einer allgemeinen Lösung.
Ich habe mir das ausgedachtsehrschmutziger Hack, aber ich bin wirklich nicht sicher, wie das hier abschneiden würde:
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
Gibt es eine einfache generische Lösung, die ich vielleicht übersehe? Oder bleibt mir keine andere Möglichkeit, als Binärdateien nach Hinweisen zu durchsuchen oder eine fest codierte Liste zu verwenden?
Antwort1
Ihre Heuristik ist ziemlich schlecht. Hier ist, was sie auf einer meiner Debian-Wheezy-Maschinen finden (ich habe korrekte Treffer manuell mit einem markiert +
).
/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 +
Wenn Sie die erste alphabetische Übereinstimmung auswählen, handelt es sich um einen Farbkalibrator.
Hier ist die Liste der Alternativen für x-terminal-emulator
, was auf diesem Debian-Rechner die richtige Antwort ist (soweit es distributionsverwaltete Programme betrifft):
/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
Sie finden 7 von 15 (unter Berücksichtigung von Namensunklarheiten), was keine sehr gute Trefferquote ist.
Sie könnten versuchen, Ihre Heuristik zu verfeinern, aber das ist ein Spiel ohne Ende. Das Minimum wäre, nur ausführbare Dateien beizubehalten, die sowohl mit einigen X11-Bibliotheken verknüpft sind als auch eine Master-Terminalfunktion oder ein Dienstprogramm wie getpt
oder aufrufen grantpt
, aber das wird zwangsläufig auch viele falsche Ergebnisse finden und ausführbare Dateien übersehen, bei denen der Aufruf in einer Bibliothek erfolgt (wie konsole
). Und dies wird ausführbare Dateien mit nativem Code übersehen, auf die über einen Shell-Wrapper zugegriffen wird (es gibt mehrere in meiner Liste).
Anhand des ausführbaren Inhalts lässt sich nicht erkennen, ob es sich bei einem Programm um einen X-Terminal-Emulator handelt.
Das Erkennen von Programmen anhand ihres Namens ist eine weitaus bessere Heuristik.
Beachten Sie auch, dass verschiedene Programme eine unterschiedliche Befehlszeilensyntax haben. Die meisten akzeptieren und , haben aber unterschiedliche Parsing-Regeln (ob über eine Shell gelaufen wird oder nicht, ob mehrere Argumente akzeptiert werden oder nicht). Daher sollten Sie nach einen einzelnen Parameter übergeben , der keine Sonderzeichen der Shell enthält.-T TITLE
-e COMMAND
-e
-e
Unter Debian und Derivatenx-terminal-emulator
ist garantiert ein X-Terminalemulator, der -T
und unterstützt -e
, sodass -e
alle nachfolgenden Befehlszeilenparameter als Befehl und dessen Argument verwendet werden und keine Shell-Erweiterung auf ihnen durchgeführt wird. Da sich einige Emulatoren anders verhalten, x-terminal-emulator
ist manchmal ein Wrapper, der eine eher xterm-ähnliche Syntax verwendet ( gnome-terminal.wrapper
und xfce4-terminal.wrapper
sind zwei Beispiele dafür).
Ich kenne so etwas bei anderen Unix-Varianten nicht. Für Portabilität ist eine fest codierte Liste von Programmnamen die beste Lösung.
Darüber hinaus gibt Ihnen die Erkennung installierter Terminalemulatoren keinen Aufschluss über die Präferenzen des Benutzers. Wenn ich beispielsweise Gnome verwende, möchte ich wahrscheinlich nicht, dass Ihre Anwendung Konsole startet – es sei denn, ich bevorzuge zufällig Konsole, aber woher sollen Sie das wissen?
Der De-facto-Standard für Benutzereinstellungen ist überFreeDesktop.orgSpezifikationen. Freedesktop veröffentlicht einexdg-utils
Paket, das Programme enthält wiexdg-open
um ein Dokument in der richtigen Anwendung zu öffnen,xdg-email
um die bevorzugte Anwendung zum Verfassen von E-Mails des Benutzers zu starten, und noch wichtigerxdg-terminal
um den bevorzugten Terminalemulator des Benutzers zu öffnen.
Dies wäre xdg-terminal
das Richtige, und Sie sollten es verwenden, wenn es vorhanden ist. Leider xdg-terminal
ist es nicht überall verfügbar; Debian liefert es beispielsweise nicht mit (es ist einFehler bei langer Inaktivität). Außerdemxdg-terminal
lässt ein einzelnes Befehlsargument zu und ist nicht konsistent hinsichtlich der Art der Erweiterung, die dieses Argument erfährt.
Was auch immer Sie tun, stellen Sie sicher, dass der Anrufer eine einfache Möglichkeit hat, seine Präferenz anzugeben. Selbst xdg-terminal
das klappt nicht immer.
Daher ist Ihre beste Strategie:
- Wenn der Benutzer eine Präferenz angegeben hat, verwenden Sie diese
- sonst versuchen
xdg-terminal
- sonst versuchen
x-terminal-emulator
- andernfalls versuchen Sie es mit einer fest codierten Liste
Antwort2
Unter Debian und Derivaten (Ubuntu, Mint, …) x-terminal-emulator
wird immer das standardmäßige grafische Terminal des Administrators gestartet.
Sie können sogar so etwas einfügen, um festzustellen, ob es sich um eine grafische Sitzung handelt:
if [ -z "$XAUTHORITY" ]
then
echo "Failed to launch terminal emulator! This is not a graphical session."
else
x-terminal-emulator
fi