201 votes

Exécution d'un fichier desktop dans le terminal

D'après ce que j'ai pu comprendre, les fichiers .desktop sont des raccourcis qui permettent de personnaliser les paramètres de l'application. Par exemple, j'en ai beaucoup dans mon dossier /usr/share/applications/.

Si j'ouvre ce dossier dans nautilus, je peux exécuter ces applications en double-cliquant simplement sur leur fichier associé, par exemple, double-cliquer sur firefox.desktop lance Firefox. Cependant, je ne trouve pas de moyen de faire la même chose via le terminal.

Si je fais gnome-open foo.desktop, cela ouvre simplement foo.desktop comme un fichier texte. Si je le rends exécutable puis le lance dans bash, cela échoue simplement (ce qui est attendu, ce n'est clairement pas un script bash).
EDIT : Faire exec /chemincomplet/foo.desktop me donne un message Permission denied, même si je change la propriété à moi-même. Si je le rends exécutable et que je fais la même commande, l'onglet terminal que j'utilise se ferme simplement (je suppose que cela plante). Enfin, si je fais sudo exec /chemincomplet/foo.desktop, j'obtiens une erreur signalant sudo : exec : command not found.

Voilà ma question, comment puis-je exécuter un fichier foo.desktop à partir du terminal?

7voto

James Broyles Points 577

Je n'ai pas de solution immédiate répondant à l'exigence d'utiliser une "commande standard", mais si vous souhaitez analyser de manière minimale les fichiers .desktop ou si vous voulez créer un alias Bash, alors ce qui suit devrait fonctionner :

  • awk -F= '/Exec=/{system($2); exit}' foo.desktop

Une autre approche qui pourrait être intéressante serait de créer une méthode binfmt-misc au niveau du noyau qui correspond aux fichiers .desktop (voir grep -r . /proc/sys/fs/binfmt_misc/ pour les modèles que vous avez actuellement activés).

En fin de compte, quelque chose quelque part devra analyser les fichiers .desktop, c'est juste une question de savoir à quel point cela est "standard / par défaut".

6voto

dukedave Points 3496

Il n'y a actuellement pas d'application dans les archives d'Ubuntu qui fait ce que vous décrivez. Il y a quelques efforts en cours pour créer une solution générale pour fournir une intégration aux environnements de bureau (comme openbox) qui ne sont pas conformes à ces spécifications XDG.

Arch Linux travaille sur une implémentation de xdg-autostart basée sur les bibliothèques python-xdg. D'après ce que je peux trouver, cela ne semble pas encore entièrement complet, mais il y a quelques rapports de succès.

Il existe également une implémentation en C++ de xdg-autostart sur gitorious (http://gitorious.org/xdg-autostart/) qui bénéficierait probablement d'une utilisation plus large.

Si l'une ou l'autre solution fonctionne pour vous, veuillez envisager de soumettre le travail nécessaire pour l'inclusion dans Debian ou Ubuntu.

Pour utiliser l'un ou l'autre outil avec openstart, vous l'appelleriez dans /etc/xdg/openbox/autostart.sh (si je lis correctement la documentation d'openbox). Si cela ne fonctionne pas, vous pouvez probablement l'appeler dans l'un des scripts d'initialisation de session d'openbox.

2voto

user119824 Points 21

Cette réponse SO est ce qui m'a aidé à clarifier les choses: ne pas essayer d'exécuter le fichier de bureau, mais exécuter le fichier pointé dans le fichier de bureau.

Par exemple, exécutez /home/jsmith/Desktop/x11vnc.sh

Exec=/home/jsmith/Desktop/x11vnc.sh

2voto

Sergiy Kolodyazhnyy Points 97292

La réponse de Hamish est excellente, mais j'aimerais suggérer une alternative plus simple, avec moins de tuyauterie impliquée :

$(awk -F= '/^Exec/||/^TryExec/ {print $2;exit}' /usr/share/applications/firefox.desktop)

Dans ce cas, awk recherche une ligne commençant par Exec, puis nous imprimons simplement les champs après cette ligne, en utilisant une boucle for et = nous imprimons le champ 2, c'est-à-dire, tout ce qui vient après ce champ. Les crochets sur les extrémités des commandes, $(...), sont une substitution de paramètre, donc le shell exécutera ce que la commande awk renvoie ; dans ce cas, elle renvoie la commande réelle qui vient après Exec=.

Dans de rares cas, il peut y avoir plus d'un signe =, ce qui reste possible. Pour cela, je suggère

$(awk -F= '/^Exec/||/^TryExec/ {for(i=2;i<=NF;i++) print $i;exit}' /usr/share/applications/firefox.desktop)

2voto

Fordi Points 291

J'ai pris le script de la réponse de Carlo ci-dessus, et j'ai essayé de l'améliorer pour mon propre usage sur le bureau.

Cette version du script vous permettra d'exécuter n'importe quelle application comme si vous l'aviez entrée dans le HUD, tant qu'il est probable que ce soit le premier résultat. Cela vous permet également de passer des arguments de fichier pour les fichiers .desktop qui ne prennent pas en charge les URI.

#!/usr/bin/env python

from gi.repository import Gio
from argparse import ArgumentParser
import sys, os

def find_app(search_string):
    for group in Gio.DesktopAppInfo.search(search_string):
        for entry in group:
            try:
                return Gio.DesktopAppInfo.new(entry)
            except: pass
    return None

def main(args):
    launcher = None
    if os.path.isfile(args.appName):
        try:
        # Si c'est un fichier, faites cela en premier.
            launcher = Gio.DesktopAppInfo.new_from_filename(args.appName)
        except TypeError:
            print "'" + args.appName + "' n'est pas un fichier .desktop"
            sys.exit(-1)
    # Si c'est un fichier .desktop dans la BD, essayez de l'utiliser
    if launcher is None and args.appName.endswith('.desktop'):
        try:
            launcher = Gio.DesktopAppInfo.new(args.appName)
        except TypeError: pass

    if launcher is None:
        # Recherchez l'application par le texte donné
        launcher = find_app(args.appName)

    if launcher is None:
        print "Aucune application nommée " + args.appName + " n'a pu être trouvée"
        sys.exit(-1)
    if (launcher.supports_uris()):
        launcher.launch_uris(args.uris, None)
    elif (launcher.supports_files()):
        launcher.launch(list({ Gio.File.parse_name(x) for x in args.uris }), None)
    else :
        launcher.launch()

if __name__ == "__main__":
    argParser = ArgumentParser(description="Lancer un fichier .desktop ou une application")
    argParser.add_argument("appName", 
        help="le nom de n'importe quelle application, le nom de base d'un fichier desktop, ou un chemin concret vers un fichier desktop", 
        action='store'
    )
    argParser.add_argument("uris", 
        nargs='*', 
        help="Fichiers ou URI à passer à l'application"
    )
    args = argParser.parse_args()
    main(args)

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X