Der richtige Weg
Sie sollten wirklich verwenden, gtk-launch
wenn es verfügbar ist. Es ist normalerweise Teil des Pakets libgtk-3-bin (dies kann je nach Distribution variieren).
gtk-launch
wird wie folgt verwendet:
gtk-launch APPLICATION [URI...]
gtk-launch app-name.desktop
gtk-launch app-name
Bitte beachten Sie, dass gtk-launch
die .desktop- Datei installiert sein muss (dh sich in /usr/share/applications
oder befindet ~/.local/share/applications
).
Um dies zu umgehen, können wir eine kleine hackige Bash-Funktion verwenden, die die gewünschte .desktop- Datei vor dem Start vorübergehend installiert . Die "richtige" Art, eine .desktop- Datei zu installieren, ist über, desktop-file-install
aber ich werde das ignorieren.
launch(){
# Usage: launch PATH [URI...]
# NOTE: The bulk of this function is executed in a subshell, i.e. `(..)`
# This isn't strictly necessary, but it keeps everything
# out of the global namespace and lessens the likelihood
# of side effects.
(
# where you want to install the launcher to
appdir=$HOME/.local/share/applications
# the template used to install the launcher
template=launcher-XXXXXX.desktop
# ensure $1 has a .desktop extension, exists, is a normal file, is readable, has nonzero size
# optionally use desktop-file-validate for stricter checking
# desktop-file-validate "$1" 2>/dev/null || {
[[ $1 = *.desktop && -f $1 && -r $1 && -s $1 ]] || {
echo "ERROR: you have not supplied valid .desktop file" >&2
return 1
}
# ensure the temporary launcher is deleted upon exit
trap 'rm "$launcherfile" &>/dev/null' EXIT
# create a temp file to overwrite later
launcherfile=$(mktemp -p "$appdir" "$template")
launchername=${launcherfile##*/}
# overwrite temp file with the launcher file
if cp "$1" "$launcherfile" &>/dev/null; then
gtk-launch "$launchername" "${@:2}"
else
echo "ERROR: failed to copy launcher to applications directory" >&2
return 1
fi
)
}
Sie können es wie folgt verwenden (und auch zusätzliche Argumente oder URIs weitergeben, wenn Sie möchten):
launch PATH [URI...]
launch ./path/to/shortcut.desktop
Die manuelle Alternative
Wenn Sie eine .desktop- Datei manuell analysieren und ausführen möchten , können Sie dies mit dem folgenden awk
Befehl tun :
awk '/^Exec=/ {sub("^Exec=", ""); gsub(" ?%[cDdFfikmNnUuv]", ""); exit system($0)}' app-name.desktop
Wenn Sie den awk
Befehl wie ein All-in-One-Skript behandeln möchten ; Wir können sogar eine Fehlermeldung anzeigen und mit dem Rückkehrcode 1 beenden, falls ein Exec- Befehl nicht gefunden wird:
awk 'BEGIN {command=""} /^Exec=/ {sub("^Exec=", ""); gsub(" ?%[cDdFfikmNnUuv]", ""); command=$0; exit} END {if (command!="") {exit system(command)} else {if (FILENAME == "-") {printf "ERROR: Failed to identify Exec line\n" > "/dev/stderr"} else {printf "ERROR: Failed to identify Exec line in \047%s\047\n", FILENAME > "/dev/stderr"} close("/dev/stderr"); exit 1}}'
Die oben genannten Befehle werden:
- Suchen Sie die Zeile, die mit Exec = beginnt
- Entfernen Sie Exec =
- Entfernen Sie alle Exec Variablen (zB
%f
, %u
, %U
). Es ist möglich, diese durch Positionsargumente zu ersetzen, wie es die Spezifikation vorsieht, dies würde dem Problem jedoch eine erhebliche Komplexität hinzufügen. Siehe neueste Desktop-Eintragsspezifikation .
- Führen Sie den Befehl aus
- Beenden Sie das Programm sofort mit dem entsprechenden Beendigungscode (um nicht mehrere Exec- Zeilen auszuführen ).
Beachten Sie, dass dieses AWK-Skript einige Randfälle behandelt, die von einigen der anderen Antworten möglicherweise nicht richtig behandelt werden. Insbesondere entfernt dieser Befehl mehrere Exec- Variablen (wobei darauf geachtet wird, das% -Symbol nicht zu entfernen), führt nur einen einzigen Exec- Zeilenbefehl aus und verhält sich erwartungsgemäß, selbst wenn der Exec- Zeilenbefehl ein oder mehrere Gleichheitszeichen enthält (z script.py --profile=name
. B. ).
Nur ein paar andere Vorbehalte ... Laut Spezifikation ist TryExec :
Pfad zu einer ausführbaren Datei auf der Festplatte, anhand derer festgestellt wird, ob das Programm tatsächlich installiert ist. Wenn der Pfad kein absoluter Pfad ist, wird die Datei in der Umgebungsvariablen $ PATH nachgeschlagen. Wenn die Datei nicht vorhanden oder nicht ausführbar ist, wird der Eintrag möglicherweise ignoriert (z. B. nicht in Menüs verwendet).
In diesem Sinne macht es keinen Sinn, seinen Wert auszuführen.
Einige andere Probleme sind Path und Terminal . Path besteht aus dem Arbeitsverzeichnis, in dem das Programm ausgeführt werden soll. Terminal ist ein Boolescher Wert, der angibt, ob das Programm in einem Terminalfenster ausgeführt wird. Diese können alle angesprochen werden, aber es macht keinen Sinn, das Rad neu zu erfinden, da es bereits Implementierungen der Spezifikation gibt. Wenn Sie Path implementieren möchten, denken Sie daran, dass system()
ein Unterprozess erzeugt wird, sodass Sie das Arbeitsverzeichnis nicht ändern können, indem Sie etwas tun wie system("cd \047" working_directory "\047"); system(command)
. Allerdings könnte man vermutlich sowas machen system("cd \047" working_directory "\047 && " command)
. Hinweis \ 047 sind einfache Anführungszeichen (damit der Befehl bei Pfaden mit Leerzeichen nicht unterbrochen wird).
Die Python-Alternative
Ich stehle eine Seite von Carlo hier , der einen Python - Skript anregte Verwendung des machen gi - Modul. Hier ist eine minimale Möglichkeit, denselben Code über die Shell auszuführen, ohne eine Datei erstellen und sich um die E / A kümmern zu müssen.
launch(){
# Usage: launch PATH [URI...]
python - "$@" <<EOF
import sys
from gi.repository import Gio
Gio.DesktopAppInfo.new_from_filename(sys.argv[1]).launch_uris(sys.argv[2:])
EOF
}
Führen Sie dann die Launcher-Funktion wie folgt aus:
launch ./path/to/shortcut.desktop
Beachten Sie, dass die Verwendung von URIs optional ist. Außerdem wird keine Fehlerprüfung durchgeführt. Sie sollten daher sicherstellen, dass der Launcher vorhanden und lesbar ist (bevor Sie ihn verwenden), wenn Ihr Skript dauerhaft sein soll.
exec
Fehler aufgetreten ist, ist, dass exec Ihren aktuell ausgeführten Prozess durch den von Ihnen angegebenen Prozess ersetzt. Sie haben also versucht, Ihre Shell durch das Ausführen des Desktops als kompilierte Binärdatei zu ersetzen. Der Grund, warum Sie das nicht konnten,sudo exec
ist, dass es sich um eine eingebaute Shell und nicht um einen Binärbefehl handelt.