Vraag Een .desktop-bestand in de terminal uitvoeren


Van wat ik kan verzamelen, .desktop bestanden zijn snelkoppelingen waarmee de instellingen van de toepassing kunnen worden aangepast. Ik heb er bijvoorbeeld veel van in mijn /usr/share/applications/ map.

Als ik die map open in nautilus, Ik kan deze toepassingen uitvoeren door te dubbelklikken op het bijbehorende bestand, bijvoorbeeld dubbelklikken firefox.desktop werkt Firefox. Ik kan echter geen manier vinden om hetzelfde via de terminal te doen.

Als ik doe gnome-open foo.desktop het opent gewoon foo.desktop als een tekstbestand. Als ik het uitvoerbaar maak en het vervolgens in bash uitvoer, mislukt het gewoon (wat naar verwachting is, het is duidelijk geen bash-script).
EDIT: Doen exec /fullpath/foo.desktop geeft me een Permission denied bericht, zelfs als ik van eigenaar verander naar mezelf. Als ik uitvoerbaar maak en het zelfde bevel voer, sluit het eindetablet dat ik gebruik eenvoudig (denk ik het het verplettert). Eindelijk, als ik dat doe sudo exec /fullpath/foo.desktop, Ik krijg een foutmelding sudo: exec: command not found.

Dat is mijn vraag, hoe kan ik een foo.desktop bestand van de terminal?


116
2017-10-04 13:58


oorsprong


NB: De reden uw exec failed is omdat exec je huidige proces vervangt door het proces dat je specificeert, dus wat je deed was proberen je shell te vervangen door het bureaublad als een gecompiled binary uit te voeren. De reden dat je dat niet kon sudo exec is omdat het een shell is gebouwd en geen binair commando is. - Daenyth
Interessant, ik vroeg me af waarom het ervoor zorgde dat het tabblad werd gesloten. - Malabarba
Verwant: Hashbang voor Gnome .desktop-bestanden - ændrük
Ik zie dat ze uiteindelijk het .desktop-bestand ontleden. Alvast bedankt voor de link. - enzotib
moderators: oeps, ik denk dat ik dit per ongeluk heb gemarkeerd, sorry als dat het geval is - Croad Langshan


antwoorden:


De opdracht die wordt uitgevoerd, bevindt zich in het bureaubladbestand, voorafgegaan door Exec= zodat je die kunt extraheren en uitvoeren door:

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

Om dat te doorbreken

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

Je zou dit bijvoorbeeld in een bestand kunnen stoppen ~/bin/deskopen met de inhoud

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

Maak het dan uitvoerbaar

chmod +x ~/bin/deskopen

En dan zou je het kunnen doen, bijvoorbeeld

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

De argumenten (%u, %F enz.) zijn te vinden op http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.0.html#exec-variables - geen van deze is relevant voor het starten op de opdrachtregel.


47
2017-10-04 14:52



Dit geeft tot nu toe het beste resultaat, maar het levert soms ongewenst gedrag op. Het gebeurt wanneer de regel "Exec =" een argument heeft zoals% u of% i. Bash probeert die reeks door te geven als een normaal argument. Bijvoorbeeld doen grep '^Exec' firefox.desktop | sed 's/^Exec=//' opent Firefox met een tabblad dat wordt geladen www.% u.com. - Malabarba
Voor het moment heb ik een seconde toegevoegd sed om argumenten te verwijderen. Maar ik denk dat er een meer "natuurlijke" manier is om het uit te voeren. - Malabarba
Ik heb mijn antwoord bijgewerkt met de extra sed - Ik vergat dat de desktop-bestanden argumenten kunnen hebben. - Hamish Downer
Je zou na "grep" een "tail -1" aan de pipe moeten toevoegen, omdat "Exec =" meerdere keren kan verschijnen, en daarna alleen de laatste verschijning moet worden uitgevoerd .. - daisy
-1: dit kan voor eenvoudig werken .desktop bestanden, maar negeert vermeldingen zoals Path= en TryExec= wat de uitvoering kan beïnvloeden. Het voert ook het verkeerde uit Exec= als het bestand bureaubladacties bevat ("snellijsten") - MestreLion


Het antwoord zou moeten zijn

xdg-open program_name.desktop

Maar vanwege een insect dit werkt niet meer.


63
2017-10-04 15:28



WoW dit is nog steeds een bug, veel vooruitgang in xdg. exo-open wordt vermeld als tijdelijke oplossing en het opent ook gedit. :( - Drew
@RichardHolloway: gnome-opendoet niet telefoontje xdg-open, het is andersom! Dus het probleem ligt in gvfs-open (de opvolger of gnome-open) - MestreLion
"werkt niet meer"? Dat deed het nooit! xdg-open werkt door mimetype association, en .desktop bestanden zijn gekoppeld aan teksteditors, omdat ze een subklasse van tekst zijn - MestreLion
dit is zo stom (dat er geen verstandige manier is om een ​​Desktop-bestand vanuit de terminal te draaien) - Sam Watkins
Deze bug is er nog steeds niet? - Noitidart


Met elke recente ubuntu die dit ondersteunt gtk-launch ga gewoon gewoon

gtk-launch <file> waar is de naam van het .desktop-bestand zonder de .desktop een deel

Zo gtk-launch foo opent foo.desktop

Als <file> is niet in /usr/share/application of de plaats waar je uitvoert gtk-launch de opdracht is gtk-launch <file> <uri>. (gtk-launch documentatie)

Bruikbaar vanaf terminal of alt + F2 (alt + F2 slaat commando in geschiedenis zo gemakkelijk toegankelijk op)


52
2017-12-02 22:32



Dit is de manier, werkt ook in debian.
gtk-launch firefox.desktop ~ / .local / share / applications / lanceert firefox de directory bekijken ~ / .local / share / applications / voor mij. Het lijkt erop dat als u gelijk had, firefox niet als een argument de directory van het .desktop-bestand had doorgegeven. Het is niet de bedoeling dat de map die aan gtk-launch is doorgegeven, wordt gebruikt om de map met het .desktop-bestand te vinden (en dat is het in feite niet) - Croad Langshan
Yay! Een antwoord dat werkt! - Alicia


Vanaf vandaag (12.10) het beestje is nog steeds aanwezig. Het is in feite afhankelijk van hoe gvfs-open (gebeld door xdg-open) werkt.

Toch slaagde ik erin een snelle oplossing te vinden (inspiratie stelen van de broncode nautilus). Het is een beetje ingewikkeld, maar werkt foutloos op Ubuntu 12.10, en voegt een zinvol pictogram toe (niet meer ?) op het Unity-opstartprogramma.

Eerst schreef ik een pythonscript met behulp van Gio en plaatste het als opgeslagen ~/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)

Het script moet de uitvoerbare machtiging hebben, dus ik heb dit in een terminal uitgevoerd:

chmod +x ~/bin/run-desktop

Toen heb ik het familielid gemaakt .desktop toegang op ~/.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

Uiteindelijk heb ik het item gekoppeld als de standaard handler in ~/.local/share/applications/mimeapps.list onder de [Default Applications] sectie als:

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

Nu:

  • xdg-open something.desktop werkt zoals verwacht
  • #!/usr/bin/xdg-open hashbang bovenop een uitvoerbaar bureaubladitem werkt ook

Het zal nutteloos werk zijn wanneer gvfs-open zal de bug oplossen, maar in de tussentijd ...


37
2018-01-11 09:06



Dit werkt beter dan Hamish Downer's antwoord omdat het met meerdere zal omgaan Exec= lijnen en % parameters in de opdracht correct. - Flimm
Bedankt voor de code - ik ben op Lucid en ik heb dit eenvoudig opgeslagen als /usr/bin/xdg-openpy, en gaf het een chmod +x - en gebruikt launcher.launch([],context) in plaats van ...None,context) (omdat "TypeError: argument 1: moet een reeks zijn, geen NoneType"). Nu xdg-openpy app.desktop werkt vanaf de opdrachtregel (en alles zoals normaal bij dubbelklikken app.desktop), en het kan me eraan herinneren als ik probeer te bellen in terminal xdg-open en druk op tab. Proost! - sdaau
1. Dit is het enige antwoord waarvoor geen handmatig parseren van de .desktop bestand, dus het is de meest gezonde (en veilige) benadering. Gebruikt ook modern gi.repository in plaats van de verouderd pygtk, zo goed! :) - MestreLion
In feite is dit een vraag met betrekking tot het antwoord van Carlo Pellegrini. Ik ben een newby, corrigeer me als er een betere manier was om het te plaatsen.Het script werkt prima, maar het pictogram dat ik in het Unity-opstartprogramma krijg, is niet het pictogram dat is gedefinieerd in het .desktop-bestand, maar het standaardpictogram van de opdracht 'Exec'ed. Enige ideeën daarover? - Ingo Leonhardt
@Noitidart schrijf het laatste antwoord led mo om wat google te doen en dat vond ik dat. Ik heb het niet gecontroleerd, maar misschien helpt het - Ingo Leonhardt


De goede weg

Je zou het echt moeten gebruiken gtk-launchals het beschikbaar is. Het maakt meestal deel uit van het pakket libgtk-3-bin (dit kan per distro variëren).

gtk-launch wordt als volgt gebruikt:

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

Houd er rekening mee dat gtk-launch vereist de .desktop bestand dat moet worden geïnstalleerd (dat wil zeggen zich bevindt in /usr/share/applications of ~/.local/share/applications).

Dus om dit te omzeilen, kunnen we een hackish kleine Bash-functie gebruiken die tijdelijk het gewenste installeert .desktop bestand voordat het wordt gestart. De "juiste" manier om een ​​te installeren .desktop bestand is via desktop-file-install maar ik zal dat negeren.

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

    )

}

Je kunt het zo gebruiken (en ook aanvullende argumenten of URI's doorgeven als je wilt):

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

Het handmatige alternatief

Als u handmatig een a wilt ontleden en uitvoeren .desktop bestand, kunt u dit doen met het volgende awk opdracht:

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

Als je de. Wilt behandelen awk commando als een alles-in-één script; we kunnen zelfs een foutmelding weergeven en afsluiten met een retourcode van 1 in het geval dat een Exec commando is niet gevonden:

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

De bovengenoemde commando's zullen:

  1. Zoek de regel die begint met Exec =
  2. Verwijderen Exec =
  3. Verwijder alle Exec-variabelen (bijv. %f, %u, %U). Het is mogelijk om deze te vervangen door positionele argumenten zoals de specificatie beoogt, maar dit zou het probleem aanzienlijk ingewikkelder maken. Zie het laatste Desktop Entry Specification.
  4. Voer het commando uit
  5. Sluit onmiddellijk af met de juiste exitcode (om niet meerdere uit te voeren Exec lijnen)

Merk op dat dit AWK-script enkele randgevallen behandelt die al dan niet op de juiste manier worden aangepakt door sommige van de andere antwoorden. In het bijzonder wordt met deze opdracht meerdere verwijderd Exec variabelen (zorg ervoor dat het% -symbool niet op andere wijze wordt verwijderd), zullen slechts één enkel getal uitvoeren Exec regel commando, en zal gedragen zoals verwacht, zelfs als de Exec lijnopdracht bevat een of meer gelijktekens (bijv. script.py --profile=name).

Nog een paar andere kanttekeningen ... Volgens de specificatie, TryExec is:

Pad naar een uitvoerbaar bestand op schijf dat wordt gebruikt om te bepalen of het programma daadwerkelijk is geïnstalleerd. Als het pad geen absoluut pad is, wordt het bestand opgezocht in de $ PATH-omgevingsvariabele. Als het bestand niet aanwezig is of niet uitvoerbaar is, kan het item worden genegeerd (niet worden gebruikt in menu's bijvoorbeeld).

Met dat in gedachten is het niet logisch om de waarde ervan uit te voeren.

Sommige andere zorgen zijn Pad en Terminal. Pad bestaat uit de werkdirectory waarin het programma wordt uitgevoerd. Terminal is een boolean die aangeeft of het programma wordt uitgevoerd in een terminalvenster. Deze kunnen allemaal worden aangepakt, maar het heeft geen zin om het wiel opnieuw uit te vinden, omdat er al implementaties van de specificatie zijn. Als je het wilt implementeren Pad, onthoud dat system() spawnt een subproces, dus je kunt de werkdirectory niet wijzigen door iets als te doen system("cd \047" working_directory "\047"); system(command). Je zou echter vermoedelijk zoiets kunnen doen system("cd \047" working_directory "\047 && " command). Opmerking \ 047 zijn enkele aanhalingstekens (dus de opdracht breekt niet op paden met spaties).

Het Python-alternatief

Ik steel een pagina van Carlo hier, die voorstelde om een ​​Python-script te maken om gebruik te maken van de gi module. Hier is een minimale manier om dezelfde code uit de shell uit te voeren zonder een bestand te hoeven maken en zorgen te hoeven maken over I / O.

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

}

Voer vervolgens de opstartfunctie als volgt uit:

launch ./path/to/shortcut.desktop

Merk op dat het gebruik van URI's optioneel is. Er wordt ook geen foutcontrole uitgevoerd, dus u moet ervoor zorgen dat het startprogramma bestaat en leesbaar is (voordat u het gebruikt) als u wilt dat uw script duurzaam is.


21
2017-08-21 19:33



Maar de awk commando is leuk. Daarom een ​​+1 - A.B.


Hoewel OP niet om KDE vroeg, kan voor iedereen die KDE gebruikt de volgende opdracht worden gebruikt:

kioclient exec <path-to-desktop-file>


19
2018-02-23 18:09



Opgewekt omdat het werkt. KDE hoeft helemaal niet te worden uitgevoerd, zolang dit programma is geïnstalleerd. - basic6
Is er een manier om hierover stdout te hebben? Ik heb clementine player gecompileerd, die een bug heeft die alleen voorkomt door te starten via .desktop-bestanden (met plasma-shell). En ik kan er niet achter komen hoe het logboek van uitvoerlogboeken ergens anders moet zijn. - Kwaadpepper
@Kwaadpepper je zou jouw .desktop -bestand kunnen gebruiken om een ​​shell-script te starten, dat intern je commando uitvoert en de uitvoer naar een bestand leidt. - Raman


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

lijkt te werken in 13.10 release, als exo-utils is geïnstalleerd (zoals het geval is met Xubuntu).


10
2017-12-22 15:45



Ja, ik heb het net getest in Ubuntu Studio 14.04. BTW. xdg-open en gvfs-open werk daar ook. - jarno
Werkt ook op 15 - Jonathan
Debian gebruiken met xfce. Werkt goed! - king_julien


Je zou kunnen gebruiken dex.

dex foo.desktop

10
2018-01-25 23:17



IMHO Dit is precies het juiste antwoord: één tool, één enkele aanroep met alleen het bestand als parameter. Dat is wat ik ook zocht om met de hand geschreven te testen .desktop bestanden. En het kan creëren .desktop ook bestanden, yay! :-) - Axel Beckert
Perfect! Als u een .desktop-bestand met dex toevoegt gist.github.com/stuaxo/4169fc1342c496b7c8f7999188f2f242  naar / usr / share / applications / u kunt bureaubladbestanden in de bestandsbeheerder starten zonder dat deze standaard ook in gedit worden geopend. - Stuart Axon


Aanvulling op het antwoord van Hamish.

Gezien het deskopen-script, kunt u een verwijzing ernaar gebruiken als de shebang-regel in a .desktop bestand, aangezien het reactieteken nog steeds is #. Dat wil zeggen, zet dit als de eerste regel van de .desktop het dossier:

#!/usr/bin/env deskopen

Markeer dan de .desktop bestand als uitvoerbaar bestand (bijvoorbeeld met een chmod +x whatever.desktop), en dan kunt u

path/to/whatever.desktop

en voila - De app gaat open! (Compleet met het pictogrambestand dat ik heb opgegeven, hoewel ik geen idee heb hoe.)

Als u nu wilt dat deskopen alle opdrachtregelparameters doorloopt, kunt u in plaats daarvan deze enigszins gewijzigde versie gebruiken:

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

Terzijde, ik probeerde het te gebruiken "#{@:2}" in plaats van shiftmaar het bleef me 'slechte vervanging' geven ...


8
2018-02-09 20:12



Ik weet dat dit een betere reactie is op het antwoord van Hamish, maar ik ben een nieuwe gebruiker en mag niet reageren. Ach ja! - pabst
Als je de reputatie hebt, zou de meest geschikte actie zijn om dat antwoord feitelijk te bewerken. - Flimm
Sla die aan, iedereen kan bewerkingen voorstellen, zelfs gebruikers die niet zijn ingelogd! Het is helemaal geen bui. - Flimm
Dit is een antwoord op zichzelf, het is goed. - Bruno Pereira
je kunt gebruiken "${@:1}" in plaats van shift, maar dat vereist bash in plaats van sh in uw #! keet. IMHO je oorspronkelijke shift-aanpak is eenvoudiger en beter - MestreLion


Er is momenteel geen applicatie die doet wat je beschrijft in de Ubuntu-archieven. Er zijn een aantal inspanningen gaande om een ​​algemene oplossing te bieden voor de integratie van desktopomgevingen (zoals een openbox) die niet voldoen aan deze XDG-specificaties.

Arch Linux werkt aan een implementatie van xdg-autostart op basis van de python-xdg-bibliotheken. Van wat ik kan vinden, lijkt dit nog niet helemaal compleet, maar heeft enkele verslagen van succes.

Er is ook een C ++ -implementatie van xdg-autostart op gitorious (http://gitorious.org/xdg-autostart/) die waarschijnlijk zou profiteren van breder gebruik.

Als een van beide oplossingen voor u werkt, overweeg dan om het benodigde werk voor opname in Debian of Ubuntu in te dienen.

Om een ​​tool met openstart te gebruiken, zou je het in /etc/xdg/openbox/autostart.sh moeten noemen (als ik de openbox documentatie goed lees). Als dit niet werkt, kunt u het waarschijnlijk in elk van de openbox-sessie-initialisatiescripts noemen.


6
2017-07-05 05:08



Niet wat ik zou willen horen, toch bedankt voor de info - enzotib