Question Exécuter un fichier .desktop dans le terminal


De ce que je peux rassembler, .desktop Les fichiers sont des raccourcis permettant de personnaliser les paramètres de l'application. Par exemple, j'en ai beaucoup dans mon /usr/share/applications/ dossier.

Si j'ouvre ce dossier dans nautilus, Je peux exécuter ces applications simplement en double-cliquant sur son fichier associé, par ex. double-clic firefox.desktop exécute Firefox. Cependant, je ne peux pas trouver un moyen de faire la même chose via un terminal.

Si je fais gnome-open foo.desktop il ouvre simplement foo.desktop sous forme de fichier texte. Si je le rend exécutable et que je l'exécute en bash, il échoue simplement (ce qui est attendu, ce n'est clairement pas le script bash).
EDIT: Faire exec /fullpath/foo.desktop me donne un Permission denied message, même si je change de propriétaire. Si je fais un exécutable et que je fais la même commande, l'onglet terminal que j'utilise se ferme simplement (je suppose qu'il se bloque). Enfin, si je le fais sudo exec /fullpath/foo.desktop, Je reçois un rapport d'erreur sudo: exec: command not found.

C'est ma question, comment puis-je exécuter un foo.desktop fichier du terminal?


116
2017-10-04 13:58


origine


NB: La raison de votre exec fail est parce que exec remplace votre processus en cours par le processus que vous spécifiez. Vous avez donc essayé de remplacer votre shell par le fonctionnement du bureau en tant que fichier binaire compilé. La raison pour laquelle vous ne pouviez pas sudo exec C'est parce que c'est un shell intégré et non une commande binaire. - Daenyth
Intéressant, je me demandais pourquoi cela provoquait la fermeture de l'onglet. - Malabarba
En relation: Hashbang pour les fichiers Gnome .desktop - ændrük
Je vois, ils finissent par analyser le fichier .desktop. Merci quand même pour le lien. - enzotib
modérateurs: oups, pense que j'ai peut-être signalé cela par hasard, désolé si c'est le cas - Croad Langshan


Réponses:


La commande qui est exécutée est contenue dans le fichier de bureau, précédée par Exec= afin que vous puissiez extraire et exécuter cela par:

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

Pour décomposer

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

Vous pourriez mettre cela dans un fichier, disons ~/bin/deskopen avec le contenu

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

Ensuite, rendez-le exécutable

chmod +x ~/bin/deskopen

Et puis vous pourriez faire, par exemple

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

Les arguments (%u, %F etc) sont détaillés à http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.0.html#exec-variables - aucun n'est pertinent pour le lancement sur la ligne de commande.


47
2017-10-04 14:52



Cela donne le meilleur résultat jusqu'ici, mais cela produit parfois un comportement indésirable. Cela se produit chaque fois que la ligne "Exec =" a un argument comme% u ou% i. Bash essaie de transmettre cette chaîne en tant qu'argument normal. Par exemple, faire grep '^Exec' firefox.desktop | sed 's/^Exec=//' ouvre Firefox avec un onglet qui charge www.% u.com. - Malabarba
Pour le moment j'ai ajouté une seconde sed pour supprimer tous les arguments. Mais je pense qu'il pourrait y avoir un moyen plus "naturel" de le faire fonctionner. - Malabarba
J'ai mis à jour ma réponse avec le sed supplémentaire - j'ai oublié que les fichiers du bureau pouvaient avoir des arguments. - Hamish Downer
Vous devez ajouter un "tail -1" au tube après "grep", car "Exec =" peut apparaître plusieurs fois, et ensuite, seule la dernière apparence doit être exécutée. - daisy
-1: Cela peut fonctionner pour simple .desktop fichiers, mais il ignore les entrées comme Path= et TryExec= ce qui peut affecter l'exécution. Il exécute également le mauvais Exec= si le fichier contient des actions de bureau ("quicklists") - MestreLion


La réponse devrait être

xdg-open program_name.desktop

Mais à cause de un bug cela ne fonctionne plus.


63
2017-10-04 15:28



WoW c'est encore un bug, beaucoup de progrès dans xdg. exo-open est répertorié comme solution de contournement et il ouvre également gedit. :( - Drew
@ RichardHolloway: gnome-openEst-ce que ne pas appel xdg-open, C'est l'inverse! Donc, le problème réside dans gvfs-open (le successeur ou gnome-open) - MestreLion
"ne fonctionne plus"? Ce n'est jamais arrivé! xdg-open travaille par association de type MIME, et .desktop les fichiers sont associés aux éditeurs de texte, car ils sont une sous-classe de texte - MestreLion
c'est tellement stupide (qu'il n'y a pas de moyen sensé d'exécuter un fichier Desktop depuis le terminal) - Sam Watkins
Ce bug est toujours là hein? - Noitidart


Avec un ubuntu récent qui supporte gtk-launch allez simplement

gtk-launch <file> où est le nom du fichier .desktop sans le .desktop partie

Alors gtk-launch foo ouvre foo.desktop

Si <file> n'est pas dans /usr/share/application ou l'endroit où vous exécutez gtk-launch la commande est gtk-launch <file> <uri>. (gtk-launch Documentation)

Utilisable depuis le terminal ou alt + F2 (alt + F2 stocke la commande dans l'historique si facilement accessible)


52
2017-12-02 22:32



C'est comme ça, ça marche aussi dans Debian.
gtk-launch firefox.desktop ~ / .local / share / applications / lance firefox affichage du répertoire ~ / .local / share / applications / pour moi. Il semblerait que si vous aviez raison, le répertoire du fichier .desktop ne devait pas être transmis à Firefox comme argument. En fait, le répertoire transmis à gtk-launch n'est pas censé être utilisé pour localiser le répertoire contenant le fichier .desktop (et ce n'est pas le cas) - Croad Langshan
Yay! Une réponse qui fonctionne! - Alicia


À partir d'aujourd'hui (12.10) l'insecte est toujours présent. En fait, cela dépend de comment gvfs-open (appelé par xdg-open) travaux.

J'ai quand même réussi une solution rapide (en s’inspirant du code source de Nautilus). C'est un peu compliqué, mais fonctionne parfaitement sur Ubuntu 12.10, ajoutant une icône significative (pas plus ?) sur le lanceur Unity.

Tout d'abord, j'ai écrit un script python en utilisant Gio et l'ai placé sous ~/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)

Le script doit avoir la permission d’exécuter, donc je l’ai exécuté dans un terminal:

chmod +x ~/bin/run-desktop

Puis j'ai créé le parent .desktop entrée sur ~/.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

Enfin, j'ai associé l'entrée comme gestionnaire par défaut dans ~/.local/share/applications/mimeapps.list sous le [Default Applications] section comme:

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

À présent:

  • xdg-open quelquechose.desktop fonctionne comme prévu
  • #!/usr/bin/xdg-open hashbang sur une entrée de bureau exécutable fonctionne aussi

Ce sera un travail inutile quand gvfs-open va résoudre le bug, mais en attendant ...


37
2018-01-11 09:06



Cela fonctionne mieux que La réponse de Hamish Downer comme il traitera de multiples Exec= lignes et % paramètres dans la commande correctement. - Flimm
Merci pour le code - je suis sur Lucid, et j'ai simplement enregistré cela comme /usr/bin/xdg-openpy, et lui a donné un chmod +x - et utilisé launcher.launch([],context) au lieu de ...None,context) (en raison de "TypeError: argument 1: Doit être une séquence, pas NoneType"). À présent xdg-openpy app.desktop fonctionne à partir de la ligne de commande (et tout comme en double-cliquant app.desktop), et cela peut me rappeler si j'essaye d'appeler au terminal xdg-open et appuyez sur l'onglet. À votre santé! - sdaau
+1. Ceci est la seule réponse qui ne nécessite pas l'analyse manuelle de la .desktop fichier, donc c'est l'approche la plus saine (et la plus sûre). Utilise également moderne gi.repository au lieu du déprécié pygtk, tellement bon! :) - MestreLion
En fait, c'est une question concernant la réponse de Carlo Pellegrini. Je suis un nouveau, corrigez-moi s'il y avait une meilleure façon de le placer. Le script fonctionne très bien, mais l'icône que j'obtiens dans le lanceur Unity n'est pas l'icône définie dans le fichier .desktop mais l'icône par défaut de la commande 'Exec'ed. Des idées à ce sujet? - Ingo Leonhardt
@Noitidart écrire la dernière réponse a conduit mo à faire un peu de google et j'ai trouvé cette. Je n'ai pas vérifié, mais peut-être que ça aide - Ingo Leonhardt


Le droit chemin

Vous devriez vraiment utiliser gtk-launchs'il est disponible Il fait généralement partie du paquet libgtk-3-bin (cela peut varier par distribution).

gtk-launch est utilisé comme suit:

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

S'il vous plaît noter que gtk-launch exige le .desktop fichier à installer (c'est-à-dire situé dans /usr/share/applications ou ~/.local/share/applications).

Pour contourner ce problème, nous pouvons utiliser une petite fonction de piratage qui installe temporairement la .desktop fichier avant de le lancer. La manière "correcte" d'installer un .desktop le fichier est via desktop-file-install mais je vais l'ignorer.

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

    )

}

Vous pouvez l'utiliser comme ça (et transmettre des arguments ou des URI supplémentaires si vous le souhaitez):

launch PATH [URI...]
launch ./path/to/shortcut.desktop

L'alternative manuelle

Si vous voulez analyser et exécuter manuellement un .desktop fichier, vous pouvez le faire avec les éléments suivants awk commander:

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

Si vous voulez traiter le awk commande comme un script tout-en-un; nous pouvons même afficher un message d'erreur et quitter avec un code retour de 1 dans le cas où un Exec la commande n'est pas trouvée:

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}}'

Les commandes susmentionnées vont:

  1. Trouvez la ligne commençant par Exec =
  2. Retirer Exec =
  3. Supprimer toutes les variables Exec (par ex. %f, %u, %U). Il est possible de les remplacer par des arguments positionnels comme prévu par la spécification, mais cela compliquerait considérablement le problème. Voir le dernier Spécification d'entrée de bureau.
  4. Exécuter la commande
  5. Quittez immédiatement avec le code de sortie approprié (afin de ne pas exécuter plusieurs Exec lignes)

Notez que ce script AWK corrige quelques cas extrêmes qui peuvent ou peuvent ne pas être correctement traités par certaines des autres réponses. Plus précisément, cette commande supprime plusieurs Exec variables (en prenant soin de ne pas supprimer le symbole%), n'exécutera qu'un seul Exec commande de ligne, et se comportera comme prévu même si le Exec commande de ligne contient un ou plusieurs signes égaux (par ex. script.py --profile=name).

Juste quelques autres réserves ... Selon le cahier des charges, TryExec est:

Chemin d'accès à un fichier exécutable sur le disque utilisé pour déterminer si le programme est réellement installé. Si le chemin n'est pas un chemin absolu, le fichier est recherché dans la variable d'environnement $ PATH. Si le fichier n'est pas présent ou s'il n'est pas exécutable, l'entrée peut être ignorée (ne pas être utilisée dans les menus, par exemple).

Dans cet esprit, exécuter sa valeur n'a pas de sens.

Certaines autres préoccupations sont Chemin et Terminal. Chemin se compose du répertoire de travail pour exécuter le programme dans. Terminal est un booléen qui indique si le programme est exécuté dans une fenêtre de terminal. Celles-ci peuvent toutes être abordées, mais il n'y a aucun sens à réinventer la roue car il y a déjà des implémentations de la spécification. Si vous voulez implémenter Chemin, garde en tête que system() génère un sous-processus, de sorte que vous ne pouvez pas modifier le répertoire de travail en faisant quelque chose comme system("cd \047" working_directory "\047"); system(command). Cependant, vous pourriez probablement faire quelque chose comme system("cd \047" working_directory "\047 && " command). Remarque \ 047 sont des guillemets simples (la commande ne se divise donc pas en chemins avec des espaces).

L'alternative python

Je vole une page de Carlo ici, qui a suggéré de créer un script Python pour utiliser le gi module. Voici un moyen minimal d'exécuter le même code depuis le shell sans avoir à créer un fichier et à vous soucier des E / S.

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

}

Ensuite, exécutez la fonction lanceur comme suit:

launch ./path/to/shortcut.desktop

Notez que l'utilisation des URI est facultative. De plus, aucune vérification des erreurs n'est effectuée, vous devez donc vous assurer que le lanceur existe et qu'il est lisible (avant de l'utiliser) si vous souhaitez que votre script soit durable.


21
2017-08-21 19:33



Mais le awk commande est sympa. Donc un +1 - A.B.


Alors que OP ne posait aucune question sur KDE, pour quiconque exécute KDE, la commande suivante peut être utilisée:

kioclient exec <path-to-desktop-file>


19
2018-02-23 18:09



Voté parce que ça marche. Pas besoin de lancer KDE du moment que ce programme est installé. - basic6
Y a-t-il un moyen d'en sortir? J'ai compilé clementine player, qui a un bug qui se produit uniquement lors du lancement via un fichier .desktop (avec plasma-shell). Et je ne peux pas comprendre, comment avoir journal de sortie de journal anywere. - Kwaadpepper
@Kwaadpepper vous pouvez utiliser votre fichier .desktop pour lancer un script shell, qui exécute en interne votre commande et redirige la sortie vers un fichier. - Raman


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

semble fonctionner dans la version 13.10, si exo-utils est installé (comme c'est le cas avec Xubuntu).


10
2017-12-22 15:45



Oui, il suffit de le tester dans Ubuntu Studio 14.04. BTW. xdg-open et gvfs-open fonctionnent là aussi. - jarno
Fonctionne dans 15 également - Jonathan
Utiliser Debian avec xfce Fonctionne très bien! - king_julien


Vous pourriez utiliser dex.

dex foo.desktop

10
2018-01-25 23:17



IMHO c'est exactement la bonne réponse: Un outil, un seul appel avec seulement le fichier en paramètre. C'est ce que je cherchais aussi pour tester l'écriture manuscrite .desktop des dossiers. Et il peut créer .desktop fichiers aussi, yay! :-) - Axel Beckert
Parfait! Si vous ajoutez un fichier .desktop qui utilise dex gist.github.com/stuaxo/4169fc1342c496b7c8f7999188f2f242  dans / usr / share / applications / vous pourrez lancer des fichiers de bureau dans le gestionnaire de fichiers sans qu’ils s’ouvrent par défaut dans gedit. - Stuart Axon


Addendum à la réponse de Hamish.

Étant donné le script deskopen, vous pouvez utiliser une référence à celle-ci comme ligne de shebang dans un .desktop fichier, puisque le caractère de commentaire est toujours #. C'est-à-dire, mettez ceci comme la première ligne du .desktop fichier:

#!/usr/bin/env deskopen

Puis marquez le .desktop fichier comme exécutable (par exemple avec un chmod +x whatever.desktop), et alors vous pouvez

path/to/whatever.desktop

et voilà - L'application va s'ouvrir! (Complet avec le fichier icône que j'ai spécifié, mais je n'ai aucune idée de comment.)

Maintenant, si vous souhaitez également que deskopen passe par tous les paramètres de ligne de commande, vous pouvez utiliser cette version légèrement modifiée:

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

En passant, j'ai essayé d'utiliser "#{@:2}" au lieu de shifting, mais il a continué à me donner "mauvaise substitution" ...


8
2018-02-09 20:12



Je sais que cela correspond plus à un commentaire de la réponse de Hamish, mais je suis un nouvel utilisateur et je ne suis pas autorisé à commenter. Tant pis! - pabst
Si vous avez la réputation, l'action la plus appropriée serait de modifier cette réponse, en fait. - Flimm
Frappez cela, n'importe qui peut suggérer des modifications, même les utilisateurs qui ne sont pas connectés! Ce n'est pas grave du tout. - Flimm
C'est une réponse à part entière, c'est bien. - Bruno Pereira
vous pouvez utiliser "${@:1}" au lieu de shift, mais cela nécessite bash au lieu de sh dans ton #! case. IMHO votre approche de changement d'origine est plus simple et meilleure - MestreLion