Frage Eine .desktop-Datei im Terminal ausführen


Von dem, was ich sammeln kann, .desktop Dateien sind Verknüpfungen, mit denen die Einstellungen der Anwendung angepasst werden können. Zum Beispiel habe ich viele von ihnen in meinem /usr/share/applications/ Mappe.

Wenn ich diesen Ordner in öffne nautilusIch kann diese Anwendungen ausführen, indem ich einfach auf die zugehörige Datei doppelklicke, z. Doppelklicken firefox.desktop Läuft Firefox. Ich finde jedoch keinen Weg, dasselbe über Terminal zu tun.

Wenn ich mache gnome-open foo.desktop es öffnet sich einfach foo.desktop als Textdatei. Wenn ich es ausführbar mache und es dann in bash laufe, scheitert es einfach (was erwartet wird, ist es eindeutig kein Bash-Skript).
Bearbeiten: Doing exec /fullpath/foo.desktop gibt mir ein Permission denied Nachricht, auch wenn ich das Eigentum an mich selbst ändere. Wenn ich eine ausführbare Datei mache und den gleichen Befehl mache, wird der Terminal-Tab, den ich benutze, einfach geschlossen (ich schätze, es stürzt ab). Schließlich, wenn ich es tue sudo exec /fullpath/foo.desktopIch erhalte eine Fehlermeldung sudo: exec: command not found.

Das ist meine Frage, wie kann ich ein laufen foo.desktop Datei vom Terminal?


116
2017-10-04 13:58


Ursprung


NB: Der Grund Ihrer exec failed ist, weil exec den gerade ausgeführten Prozess durch den von Ihnen angegebenen Prozess ersetzt. Sie haben also versucht, Ihre Shell durch Ausführen des Desktops als kompilierte Binärdatei zu ersetzen. Der Grund, warum Sie nicht konnten sudo exec ist, weil es eine eingebaute Shell ist und kein binärer Befehl. - Daenyth
Interessant, ich habe mich gefragt, warum der Tab geschlossen wurde. - Malabarba
Verbunden: Hashbang für Gnome .desktop-Dateien - ændrük
Ich sehe, sie analysieren die .desktop-Datei. Danke trotzdem für den Link. - enzotib
Moderatoren: Hoppla, ich denke, ich habe das versehentlich angezeigt, tut mir leid, wenn das der Fall ist - Croad Langshan


Antworten:


Der Befehl, der ausgeführt wird, ist in der Desktop-Datei enthalten Exec= also könntest du das extrahieren und ausführen:

`grep '^Exec' filename.desktop | tail -1 | sed 's/^Exec=//' | sed 's/%.//' | sed 's/^"//g' | sed 's/" *$//g'` &

Um das zu brechen

grep  '^Exec' filename.desktop    - finds the line which starts with Exec
| tail -1                         - only use the last line, in case there are multiple
| sed 's/^Exec=//'                - removes the Exec from the start of the line
| sed 's/%.//'                    - removes any arguments - %u, %f etc
| sed 's/^"//g' | sed 's/" *$//g' - removes " around command (if present)
`...`                             - means run the result of the command run here
&                                 - at the end means run it in the background

Du könntest das zum Beispiel in eine Datei schreiben ~/bin/deskopen mit dem Inhalt

#!/bin/sh
`grep '^Exec' $1 | tail -1 | sed 's/^Exec=//' | sed 's/%.//' | sed 's/^"//g' | sed 's/" *$//g'` &

Dann mach es ausführbar

chmod +x ~/bin/deskopen

Und dann könntest du, z

deskopen /usr/share/applications/ubuntu-about.desktop

Die Argumente (%u, %F etc) sind detailliert unter http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.0.html#exec-variables - Keiner von ihnen ist relevant für den Start in der Befehlszeile.


47
2017-10-04 14:52



Dies ergibt das bisher beste Ergebnis, erzeugt jedoch manchmal ein unerwünschtes Verhalten. Dies geschieht immer dann, wenn die Zeile "Exec =" ein Argument wie% u oder% i enthält. Bash versucht, diese Zeichenfolge als reguläres Argument zu übergeben. Zum Beispiel, zu tun grep '^Exec' firefox.desktop | sed 's/^Exec=//' Öffnet Firefox mit einem Tab, der geladen wird www.% u.com. - Malabarba
Für den Moment habe ich eine Sekunde hinzugefügt sed um irgendwelche Argumente zu entfernen. Aber ich denke, dass es einen "natürlicheren" Weg geben könnte. - Malabarba
Ich habe meine Antwort mit dem zusätzlichen Sed aktualisiert - ich habe vergessen, dass die Desktop-Dateien Argumente haben könnten. - Hamish Downer
Sie sollten nach "grep" ein "tail -1" zur Pipe hinzufügen, da "Exec =" mehrfach vorkommen kann und danach nur die letzte Darstellung ausgeführt werden soll. - daisy
-1: Das mag für simple funktionieren .desktop Dateien, aber es ignoriert Einträge wie Path= und TryExec= was die Ausführung beeinflussen kann. Es führt auch das Falsche aus Exec= wenn die Datei Desktop-Aktionen enthält ("Quicklists") - MestreLion


Die Antwort sollte sein

xdg-open program_name.desktop

Aber wegen ein Käfer das funktioniert nicht mehr.


63
2017-10-04 15:28



WoW das ist immer noch ein Fehler, viel Fortschritt in xdg. exo-open wird als Workaround aufgeführt und es öffnet sich auch gedit. :( - Drew
@RichardHolloway: gnome-opentut nicht Anruf xdg-open, es ist anders herum! Also das Problem liegt in gvfs-open (der Nachfolger oder gnome-open) - MestreLion
"funktioniert nicht mehr"? Es hat nie getan! xdg-open funktioniert durch Mimetype-Zuordnung und .desktop Dateien sind Texteditoren zugeordnet, da sie eine Unterklasse von Text sind - MestreLion
das ist so dumm (dass es keine vernünftige Möglichkeit gibt, eine Desktop-Datei vom Terminal aus auszuführen) - Sam Watkins
Dieser Fehler ist immer noch da, nicht wahr? - Noitidart


Mit jedem neueren Ubuntu, das unterstützt gtk-launch geh einfach

gtk-launch <file> wo ist der Name der .desktop-Datei ohne die .desktop-Datei .desktop Teil

Damit gtk-launch foo öffnet foo.desktop

Ob <file> ist nicht in /usr/share/application oder der Ort, an dem du ausführst gtk-launch der Befehl ist gtk-launch <file> <uri>. (gtk-launch Dokumentation)

Verwendbar von Terminal oder Alt + F2 (Alt + F2 speichert den Befehl in der Geschichte so leicht zugänglich)


52
2017-12-02 22:32



So funktioniert es auch in debian.
gtk-launch firefox.desktop ~ / .local / share / applications / startet Firefox Anzeigen des Verzeichnisses ~ / .local / share / applications / für mich. Scheint, wenn du richtig warst, hätte firefox das Verzeichnis der .desktop-Datei nicht als Argument übergeben werden sollen. Tatsächlich sollte das Verzeichnis, das an gtk-launch übergeben wird, nicht dazu verwendet werden, das Verzeichnis zu finden, das die .desktop-Datei enthält (und das ist es tatsächlich nicht) - Croad Langshan
Yay! Eine Antwort, die funktioniert! - Alicia


Ab heute (12.10) der Fehler ist noch da. Es hängt tatsächlich davon ab, wie gvfs-open (angerufen von xdg-open) funktioniert.

Dennoch schaffte ich eine schnelle Abhilfe (stiehlt Inspiration aus dem Nautilus Quellcode). Es ist ein wenig verschachtelt, funktioniert aber einwandfrei auf Ubuntu 12.10 und fügt ein bedeutungsvolles Symbol hinzu (nicht mehr ?) auf dem Unity-Launcher.

Zuerst schrieb ich ein Python-Skript mit Gio und platzierte es als gespeichert ~/bin/run-desktop :

#!/usr/bin/python

from gi.repository import Gio
import sys 

def main(myname, desktop, *uris):
    launcher = Gio.DesktopAppInfo.new_from_filename(desktop)
    launcher.launch_uris(uris, None)

if __name__ == "__main__":
    main(*sys.argv)

Das Skript benötigt die ausführbare Berechtigung, also habe ich das in einem Terminal ausgeführt:

chmod +x ~/bin/run-desktop

Dann habe ich den Verwandten erschaffen .desktop Eintritt auf ~/.local/share/applications/run-desktop.desktop:

[Desktop Entry]
Version=1.0
Name=run-desktop
Exec=run-desktop %U
MimeType=application/x-desktop
Terminal=false
Type=Application

Schließlich habe ich den Eintrag als Standardhandler in ~/.local/share/applications/mimeapps.list unter dem [Default Applications] Abschnitt als:

[Default Applications]
....
application/x-desktop=run-desktop.desktop

Jetzt:

  • xdg-open something.desktop funktioniert wie erwartet
  • #!/usr/bin/xdg-open Hashbang über einem ausführbaren Desktop-Eintrag funktioniert auch

Es wird nutzlos sein, wenn gvfs-open wird den Fehler beheben, aber in der Zwischenzeit ...


37
2018-01-11 09:06



Das funktioniert besser als Hamish Downers Antwort wie es mit mehreren umgehen wird Exec= Linien und % Parameter im Befehl korrekt. - Flimm
Danke für den Code - ich bin auf Lucid, und ich habe das einfach als gerettet /usr/bin/xdg-openpyund gab es a chmod +x - und benutzt launcher.launch([],context) Anstatt von ...None,context) (durch "TypeError: Argument 1: Muss Sequenz sein, nicht NoneType"). Jetzt xdg-openpy app.desktop funktioniert über die Befehlszeile (und alles wie gewohnt beim Doppelklicken app.desktop), und es kann mich erinnern, wenn ich versuche, Terminal anzurufen xdg-open und drücke Tab. Prost! - sdaau
+1. Dies ist die einzige Antwort, die keine manuelle Analyse des .desktop Datei, also ist es der vernünftigste (und sicherste) Ansatz. Verwendet auch modern gi.repository anstelle der veralteten pygtk, So großartig! :) - MestreLion
In der Tat handelt es sich um eine Frage, die Carlo Pellegrinis Antwort betrifft. Ich bin ein Newby, korrigiere mich bitte, wenn es einen besseren Weg gibt, es zu platzieren.Das Skript funktioniert wirklich gut, aber das Symbol, das ich auf dem Unity-Launcher erhalte, ist nicht das in der .desktop-Datei definierte Symbol, sondern das Standard-Icon des 'Exec'ed-Befehls. Irgendwelche Ideen dazu? - Ingo Leonhardt
@Noitidart schreibe die letzte Antwort führte mo, um etwas Google zu tun, und ich fand Das. Habe es nicht überprüft, aber vielleicht hilft es - Ingo Leonhardt


Der richtige Weg

Sie sollten wirklich verwenden gtk-launchwenn es verfügbar ist. Es ist normalerweise ein Teil des Pakets libgtk-3-bin (Dies kann von Distro variieren).

gtk-launch wird wie folgt verwendet:

gtk-launch APPLICATION [URI...]
gtk-launch app-name.desktop
gtk-launch app-name

Bitte beachte, dass gtk-launch benötigt die .desktop Datei, die installiert werden soll (d. h. in /usr/share/applications oder ~/.local/share/applications).

Um dies zu umgehen, können wir eine kleine Hash-Funktion verwenden, die das gewünschte temporär installiert .desktop Datei vor dem Start. Der "richtige" Weg, um ein .desktop Datei ist via 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 manuell a analysieren und ausführen möchten .desktop Datei, können Sie dies mit dem folgenden tun awk Befehl:

awk '/^Exec=/ {sub("^Exec=", ""); gsub(" ?%[cDdFfikmNnUuv]", ""); exit system($0)}' app-name.desktop

Wenn Sie das behandeln möchten awk Befehl wie ein All-in-One-Skript; wir können sogar eine Fehlermeldung anzeigen und mit einem Rückkehrcode von 1 beenden, falls ein Exec Befehl wurde nicht gefunden:

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:

  1. Finde die Zeile, die mit beginnt Exec =
  2. Löschen Exec =
  3. Entfernen Sie alle Exec-Variablen (z. %f, %u, %U). Es ist möglich, diese durch Positionsargumente zu ersetzen, wie es die Spezifikation vorsieht, aber dies würde das Problem erheblich komplizierter machen. Siehe spätestens Desktop-Eintragsspezifikation.
  4. Führe den Befehl aus
  5. Sofort mit dem entsprechenden Exit-Code beenden (um nicht mehrere auszuführen) Exec Linien)

Beachten Sie, dass dieses AWK-Skript einige Randfälle anspricht, die von einigen der anderen Antworten möglicherweise richtig behandelt werden. Insbesondere entfernt dieser Befehl mehrere Exec Variablen (achten Sie darauf, das Symbol% ​​nicht zu entfernen), wird nur eine einzige ausgeführt Exec Zeilenbefehl und verhält sich wie erwartet, auch wenn der Exec Zeilenbefehl enthält ein oder mehrere Gleichheitszeichen (z. script.py --profile=name).

Nur ein paar andere Vorbehalte ... Laut Spezifikation, TryExec ist:

Pfad zu einer ausführbaren Datei auf der Festplatte, mit der 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, kann der Eintrag ignoriert werden (z. B. nicht in Menüs verwendet werden).

In diesem Sinne macht es keinen Sinn, seinen Wert zu erfüllen.

Einige andere Bedenken sind Pfad und Terminal. Pfad 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 hat keinen Sinn, das Rad neu zu erfinden, da es bereits Implementierungen der Spezifikation gibt. Wenn Sie das implementieren möchten Pfad, Denk daran, dass system() erzeugt einen Subprozess, so dass Sie das Arbeitsverzeichnis nicht ändern können, indem Sie etwas tun system("cd \047" working_directory "\047"); system(command). Allerdings könnte man vermutlich sowas machen system("cd \047" working_directory "\047 && " command). Note \ 047 sind einfache Anführungszeichen (der Befehl bricht also bei Pfaden mit Leerzeichen nicht).

Die Python-Alternative

Ich stiehl eine Seite von Carlo Hier, der vorgeschlagen hat, ein Python - Skript zu erstellen, um die Gi Modul. Hier ist ein minimaler Weg, denselben Code von der Shell auszuführen, ohne eine Datei erstellen zu müssen und sich um I / O Sorgen zu machen.

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 Startfunktion wie folgt aus:

launch ./path/to/shortcut.desktop

Beachten Sie, dass die Verwendung von URIs optional ist. Außerdem wird keine Fehlerüberprüfung durchgeführt. Daher sollten Sie sicherstellen, dass das Startprogramm vorhanden und lesbar ist (bevor Sie es verwenden), wenn das Skript dauerhaft sein soll.


21
2017-08-21 19:33



Aber die awk Befehl ist nett. Daher ein +1 - A.B.


Während OP nicht nach KDE gefragt hat, kann für jeden, der KDE ausführt, der folgende Befehl verwendet werden:

kioclient exec <path-to-desktop-file>


19
2018-02-23 18:09



Upvoted, weil es funktioniert. Sie müssen KDE überhaupt nicht ausführen, solange Sie dieses Programm installiert haben. - basic6
Gibt es eine Möglichkeit, dies zu vermeiden? Ich habe den Clementine-Player kompiliert, der einen Fehler hat, der nur durch die .desktop-Datei (mit Plasma-Shell) auftritt. Und ich kann nicht herausfinden, wie man log log anywere ausgegeben hat. - Kwaadpepper
@Kwaadpepper Sie könnten Ihre .desktop-Datei verwenden, um ein Shell-Skript zu starten, das Ihren Befehl intern ausführt und die Ausgabe in eine Datei umleitet. - Raman


exo-open [[path-to-a-desktop-file]...]

scheint in Version 13.10 zu funktionieren, wenn exo-utils installiert ist (wie es bei Xubuntu der Fall ist).


10
2017-12-22 15:45



Ja, habe es gerade in Ubuntu Studio 14.04 getestet. Übrigens. xdg-open und gvfs-open funktionieren auch dort. - jarno
Funktioniert auch in 15 - Jonathan
Debian mit xfce verwenden. Funktioniert super! - king_julien


Du könntest benutzen Dex.

dex foo.desktop

10
2018-01-25 23:17



IMHO das ist genau die richtige Antwort: Ein Tool, ein einzelner Aufruf mit nur der Datei als Parameter. Das habe ich auch gesucht, um handgeschrieben zu testen .desktop Dateien. Und es kann schaffen .desktop Dateien auch, yay! :-) - Axel Beckert
Perfekt! Wenn Sie eine .desktop-Datei hinzufügen, die dex verwendet gist.github.com/stuaxo/4169fc1342c496b7c8f7999188f2f242  nach / usr / share / applications / Sie können Desktop-Dateien im Dateimanager starten, ohne dass diese standardmäßig in gedit geöffnet werden. - Stuart Axon


Nachtrag zu Hamishs Antwort.

Angesichts des Deskopen-Skripts können Sie einen Verweis darauf als die Shebang-Zeile in einem verwenden .desktop Datei, da das Kommentarzeichen noch steht #. Das heißt, dies als die erste Zeile der .desktop Datei:

#!/usr/bin/env deskopen

Dann markieren Sie die .desktop Datei als ausführbare Datei (z. B. mit einem chmod +x whatever.desktop), und dann können Sie

path/to/whatever.desktop

und voilà - Die App wird geöffnet! (Komplett mit der Icon-Datei, die ich angegeben habe, obwohl ich keine Ahnung habe, wie.)

Wenn Sie möchten, dass Deskopen auch beliebige Befehlszeilenparameter durchläuft, können Sie stattdessen diese leicht modifizierte Version verwenden:

#!/bin/sh
desktop_file=$1
shift
`grep '^Exec' "${desktop_file}" | sed 's/^Exec=//' | sed 's/%.//'` "$@" &

Nebenbei habe ich versucht zu verwenden "#{@:2}" Anstatt von shifting, aber es hat mir immer "schlechte Substitution" gegeben ...


8
2018-02-09 20:12



Ich weiß, dass dies eher ein Kommentar zu Hamishs Antwort ist, aber ich bin ein neuer Benutzer und darf nicht kommentieren. Naja! - pabst
Wenn Sie den Ruf haben, wäre die am besten geeignete Maßnahme, diese Antwort tatsächlich zu bearbeiten. - Flimm
Strike, dass jeder Änderungen vorschlagen kann, sogar Benutzer, die nicht eingeloggt sind! Es ist kein Biggie auf irgendeine Weise. - Flimm
Dies ist eine Antwort an sich, es ist in Ordnung. - Bruno Pereira
Sie können verwenden "${@:1}" Anstatt von shift, aber das erfordert bash Anstatt von sh in deinem #! Shebang. IMHO ist Ihre ursprüngliche Schichtmethode einfacher und besser - MestreLion


Es gibt derzeit keine Anwendung, die das tut, was Sie in den Ubuntu-Archiven beschreiben. Es gibt einige Bemühungen, eine allgemeine Lösung für die Integration in Desktop-Umgebungen (wie Openbox) zu entwickeln, die nicht mit diesen XDG-Spezifikationen kompatibel sind.

Arch Linux arbeitet an einer Implementierung von xdg-autostart basierend auf den python-xdg-Bibliotheken. Von dem, was ich finden kann, scheint dies noch nicht vollständig abgeschlossen zu sein, aber es gibt Berichte über Erfolg.

Es gibt auch eine C ++ - Implementierung von xdg-autostart auf gitorious (http://gitorious.org/xdg-autostart/), die wahrscheinlich von einer weiteren Verwendung profitieren würde.

Wenn eine der beiden Lösungen für Sie arbeitet, sollten Sie in Erwägung ziehen, die notwendige Arbeit für die Aufnahme in Debian oder Ubuntu einzureichen.

Um eines der Werkzeuge mit Openstart zu verwenden, würden Sie es in /etc/xdg/openbox/autostart.sh aufrufen (wenn ich die openbox-Dokumentation korrekt lese). Wenn dies nicht funktioniert, können Sie es wahrscheinlich in einem der Initialisierungsskripts für die Openbox-Sitzung aufrufen.


6
2017-07-05 05:08



Nicht was ich hören würde, trotzdem danke für die Info - enzotib