Menjalankan file .desktop di terminal


142

Dari apa yang dapat saya kumpulkan, .desktopfile adalah pintasan yang memungkinkan pengaturan aplikasi disesuaikan. Misalnya, saya punya banyak di /usr/share/applications/folder saya .

Jika saya membuka folder itu nautilus, saya dapat menjalankan aplikasi ini hanya dengan mengklik dua kali file yang terkait, misalnya mengklik dua kali firefox.desktopmenjalankan Firefox. Namun, saya tidak dapat menemukan cara untuk melakukan hal yang sama melalui terminal.

Jika saya melakukannya gnome-open foo.desktopcukup buka foo.desktopsebagai file teks. Jika saya membuatnya dapat dieksekusi dan kemudian menjalankannya di bash hanya gagal (yang diharapkan, itu jelas bukan skrip bash).
EDIT: Melakukan exec /fullpath/foo.desktopmemberi saya Permission deniedpesan, bahkan jika saya mengubah kepemilikan untuk diri saya sendiri. Jika saya membuat executable dan melakukan perintah yang sama, tab terminal yang saya gunakan cukup ditutup (saya kira itu crash). Akhirnya, jika saya lakukan sudo exec /fullpath/foo.desktop, saya mendapatkan pelaporan kesalahan sudo: exec: command not found.

Itu pertanyaan saya, bagaimana saya bisa menjalankan foo.desktopfile dari terminal?


5
NB: Alasan execkegagalan Anda adalah karena exec mengganti proses yang sedang berjalan dengan proses yang Anda tentukan, jadi yang Anda lakukan adalah mencoba mengganti shell Anda dengan menjalankan desktop sebagai biner yang dikompilasi. Alasan Anda tidak bisa sudo execkarena itu adalah builtin shell dan bukan perintah biner.
Daenyth

Menarik, saya bertanya-tanya mengapa itu menyebabkan tab tutup.
Malabarba


Begitu ya, mereka akhirnya mem-parsing file .desktop. Terima kasih atas tautannya.
enzotib

moderator: oops, saya pikir saya mungkin telah menandai ini secara tidak sengaja, maaf jika itu masalahnya
Croad Langshan

Jawaban:


54

Perintah yang dijalankan terdapat di dalam file desktop, didahului oleh Exec=sehingga Anda dapat mengekstrak dan menjalankannya dengan:

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

Untuk memecahnya

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

Anda bisa meletakkan ini di file, katakan ~/bin/deskopendengan konten

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

Kemudian buat itu bisa dieksekusi

chmod +x ~/bin/deskopen

Dan kemudian Anda bisa melakukannya, misalnya

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

Argumen ( %u, %Fdll) dirinci di http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.0.html#exec-variables - tidak ada satupun yang relevan untuk diluncurkan di baris perintah .


Ini memberikan hasil terbaik sejauh ini, tetapi terkadang menghasilkan perilaku yang tidak diinginkan. Ini terjadi setiap kali baris "Exec =" memiliki argumen seperti% u atau% i. Bash mencoba meneruskan string itu sebagai argumen biasa. Misalnya, melakukan grep '^Exec' firefox.desktop | sed 's/^Exec=//'membuka Firefox dengan tab yang memuat www.% U.com .
Malabarba

Untuk saat ini saya telah menambahkan sedetik seduntuk menghapus argumen apa pun. Tapi saya pikir mungkin ada cara yang lebih "alami" untuk menjalankannya.
Malabarba

Saya telah memperbarui jawaban saya dengan sed tambahan - Saya lupa file desktop dapat memiliki argumen.
Hamish Downer

Anda harus menambahkan "tail -1" ke pipa setelah "grep", karena "Exec =" dapat muncul berulang kali, dan setelah itu, hanya penampilan terakhir yang harus dieksekusi ..
daisy

13
-1: Ini dapat berfungsi untuk .desktopfile sederhana , tetapi mengabaikan entri seperti Path=dan TryExec=yang dapat mempengaruhi eksekusi. Ini juga mengeksekusi yang salah Exec=jika file tersebut berisi Tindakan Desktop ("daftar cepat")
MestreLion

85

Jawabannya seharusnya

xdg-open program_name.desktop

Tetapi karena bug ini tidak lagi berfungsi.


7
WoW ini masih bug, banyak kemajuan di xdg. exo-openterdaftar sebagai solusi dan juga membuka gedit. :(
Drew

1
@RichardHolloway: gnome-opentidak tidak menyebutnya xdg-open, itu sebaliknya! Jadi masalahnya terletak pada gvfs-open(penerus atau gnome-open)
MestreLion

13
"tidak lagi berfungsi"? Tidak pernah berhasil! xdg-openberfungsi oleh asosiasi mimetype, dan .desktopfile dikaitkan dengan editor teks, karena mereka adalah subkelas teks
MestreLion

13
ini sangat bodoh (bahwa tidak ada cara yang masuk akal untuk menjalankan file Desktop dari terminal)
Sam Watkins

2
Bekerja untuk saya di Arch Linux, tapi mungkin itu bug khusus Ubuntu.
Victor

76

Dengan setiap ubuntu terbaru yang mendukung gtk-launchcukup pergi

gtk-launch <file>di mana nama file .desktop dengan atau tanpa .desktopbagian

Jadi gtk-launch footerbukafoo.desktop

( gtk-launchdokumentasi )

.Desktop harus di / usr / share / aplikasi, / usr / local / share / aplikasi atau ~ / .local / share / aplikasi

Dapat digunakan dari terminal atau alt + F2 (alt + F2 menyimpan perintah dalam sejarah sehingga mudah diakses)


Ini caranya, bekerja di debian juga.

gtk-launch firefox.desktop ~ / .local / share / application / meluncurkan firefox melihat direktori ~ / .local / share / aplikasi / untuk saya. Sepertinya Anda benar, firefox seharusnya tidak melewati direktori file .desktop sebagai argumen. Bahkan direktori yang dilewatkan ke gtk-launch tidak seharusnya digunakan untuk menemukan direktori yang berisi file .desktop (dan sebenarnya bukan)
Croad Langshan

Yay! Jawaban yang berhasil!
Alicia

Ini TIDAK bekerja untuk saya di Arch Linux juga. Tidak ada jawaban lain yang memuaskan, tetapi jawaban ini bagus. :-) Ini bekerja meskipun saya menjalankan KDE.
MountainX

2
Tidak ada versi ini yang berfungsi untuk saya di Ubuntu 18.10. Setiap kali komplain aplikasi tidak ada, apakah saya di folder dengan file desktop atau tidak, apakah saya menyertakan ekstensi .desktop atau tidak, dan apakah saya secara terpisah memberi nama direktori atau tidak.
Joseph Garvin

38

Sampai hari ini (12.10) bug masih ada. Itu sebenarnya tergantung pada bagaimana gvfs-open(dipanggil oleh xdg-open) bekerja.

Namun, saya berhasil menyelesaikannya dengan cepat (mencuri inspirasi dari kode sumber nautilus). Ini agak berbelit-belit, tetapi bekerja dengan sempurna di Ubuntu 12.10, menambahkan ikon yang bermakna (tidak lebih ?) pada peluncur Unity.

Pertama, saya menulis skrip python menggunakan Gio dan menempatkannya sebagai ~/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)

Skrip harus memiliki izin yang dapat dieksekusi, jadi saya menjalankan ini di terminal:

chmod +x ~/bin/run-desktop

Lalu saya membuat .desktopentri relatif pada ~/.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

Akhirnya saya menghubungkan entri sebagai pengendali default di ~/.local/share/applications/mimeapps.listbawah [Default Applications]bagian sebagai:

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

Sekarang:

  • xdg-open something.desktop berfungsi seperti yang diharapkan
  • #!/usr/bin/xdg-open hashbang di atas entri desktop yang dapat dieksekusi juga berfungsi

Ini akan menjadi pekerjaan sia-sia ketika gvfs-openakan menyelesaikan bug, tetapi sementara itu ...


1
Ini berfungsi lebih baik daripada jawaban Hamish Downer karena akan menangani beberapa Exec=baris dan %parameter dalam perintah dengan benar.
Flimm

4
Terima kasih untuk kodenya - Saya menggunakan Lucid, dan saya hanya menyimpan ini sebagai /usr/bin/xdg-openpy, dan memberinya chmod +x- dan digunakan launcher.launch([],context)sebagai gantinya ...None,context)(karena " TypeError: argumen 1: Harus berurutan, bukan NoneType "). Sekarang xdg-openpy app.desktopberfungsi dari baris perintah (dan semua seperti biasa ketika mengklik dua kali app.desktop), dan itu dapat mengingatkan saya jika saya mencoba menelepon terminal xdg-opendan tekan tab. Tepuk tangan!
sdaau

3
+1. Ini adalah satu-satunya jawaban yang tidak memerlukan parsing .desktopfile secara manual , jadi ini adalah pendekatan yang paling waras (dan aman). Juga menggunakan modern, gi.repositorybukan usang pygtk, begitu hebat! :)
MestreLion

2
Sebenarnya, ini adalah pertanyaan tentang jawaban Carlo Pellegrini. Saya baru, tolong perbaiki saya jika ada cara yang lebih baik untuk menempatkannya. Script berfungsi dengan sangat baik, tetapi ikon yang saya dapatkan di peluncur Unity bukan ikon yang ditentukan dalam file .desktop tetapi ikon default dari perintah 'Exec'ed. Ada ide tentang itu?
Ingo Leonhardt

1
@ Noitart menulis jawaban terakhir yang dipimpin mo untuk melakukan beberapa google dan saya menemukan itu . Belum memeriksanya, tapi mungkin ini membantu
Ingo Leonhardt

31

Jalan yang benar

Anda harus benar-benar menggunakan gtk-launchjika tersedia. Biasanya merupakan bagian dari paket libgtk-3-bin (ini mungkin berbeda-beda menurut distro).

gtk-launch digunakan sebagai berikut:

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

Harap dicatat bahwa gtk-launchmemerlukan file .desktop untuk diinstal (yaitu terletak di /usr/share/applicationsatau ~/.local/share/applications)

Jadi untuk menyiasatinya, kita dapat menggunakan fungsi Bash kecil yang bersifat sementara yang menginstal sementara file .desktop yang diinginkan sebelum meluncurkannya. Cara "benar" untuk menginstal file .desktop adalah melalui desktop-file-installtetapi saya akan mengabaikannya.

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

    )

}

Anda dapat menggunakannya seperti itu (dan juga berikan argumen tambahan atau URI jika Anda mau):

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

Alternatif Manual

Jika Anda ingin mem-parsing dan mengeksekusi file .desktop secara manual , Anda dapat melakukannya dengan awkperintah berikut :

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

Jika Anda ingin memperlakukan awkperintah seperti skrip all-in-one; kita bahkan dapat menampilkan pesan kesalahan dan keluar dengan kode pengembalian 1 jika perintah Exec tidak ditemukan:

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

Perintah-perintah tersebut akan:

  1. Temukan baris yang dimulai dengan Exec =
  2. Hapus Exec =
  3. Hapus semua variabel Exec (misalnya %f, %u, %U). Dimungkinkan untuk mengganti ini dengan argumen posisional sesuai spesifikasi yang dimaksudkan, tetapi melakukan hal itu akan menambah kompleksitas yang signifikan pada masalah. Lihat Spesifikasi Entri Desktop terbaru .
  4. Jalankan perintah
  5. Segera keluar dengan kode keluar yang sesuai (agar tidak mengeksekusi beberapa baris Exec )

Catatan, skrip AWK ini membahas beberapa kasus tepi yang mungkin atau mungkin tidak ditangani dengan benar oleh beberapa jawaban lainnya. Secara khusus, perintah ini menghapus beberapa variabel Exec (berhati-hati untuk tidak menghilangkan simbol%), hanya akan mengeksekusi satu perintah baris Exec , dan akan berperilaku seperti yang diharapkan bahkan jika perintah baris Exec berisi satu atau lebih tanda sama dengan (misalnya script.py --profile=name).

Hanya beberapa peringatan lainnya ... Menurut spesifikasi, TryExec adalah:

Path ke file yang dapat dieksekusi pada disk yang digunakan untuk menentukan apakah program tersebut benar-benar diinstal. Jika path bukan path absolut, file tersebut dicari dalam variabel lingkungan $ PATH. Jika file tidak ada atau jika tidak dapat dieksekusi, entri dapat diabaikan (misalnya, tidak digunakan dalam menu).

Dengan pemikiran itu, tidak masuk akal untuk mengeksekusi nilainya.

Beberapa masalah lain adalah Path dan Terminal . Path terdiri dari direktori kerja untuk menjalankan program. Terminal adalah boolean yang menunjukkan apakah program dijalankan di jendela terminal. Ini semua dapat diatasi, tetapi tidak ada gunanya menciptakan kembali roda karena sudah ada implementasi dari spesifikasi. Jika Anda ingin mengimplementasikan Path , perlu diingat bahwa system()memunculkan subproses, sehingga Anda tidak dapat mengubah direktori kerja dengan melakukan sesuatu seperti system("cd \047" working_directory "\047"); system(command). Namun Anda mungkin bisa melakukan sesuatu seperti system("cd \047" working_directory "\047 && " command). Catatan \ 047 adalah tanda kutip tunggal (sehingga perintah tidak memecah jalur dengan spasi).

Alternatif Python

Saya mencuri halaman dari Carlo di sini , yang menyarankan untuk membuat skrip Python untuk menggunakan modul gi . Inilah cara minimal untuk mengeksekusi kode yang sama dari shell tanpa harus membuat file dan khawatir tentang 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

}

Kemudian jalankan fungsi launcher sebagai berikut:

launch ./path/to/shortcut.desktop

Perhatikan bahwa penggunaan URI bersifat opsional. Selain itu, tidak ada pemeriksaan kesalahan yang dilakukan sehingga Anda ingin memastikan peluncur ada dan dapat dibaca (sebelum menggunakannya) jika Anda ingin skrip Anda tahan lama.


Tapi awkperintahnya bagus. Oleh karena itu +1
AB

Apa itu URI dalam konteks ini? Saya memiliki file desktop di folder sewenang-wenang. Bagaimana sih saya menjalankan gtk-launch di atasnya tanpa harus membungkusnya dengan skrip lain? Ini menjengkelkan.
Joseph Garvin

Ini awksolusi tidak akan benar bekerja jika perintah memiliki spasi putih ganda melarikan diri atau garis miring terbalik. Itu rusak pada ini: Exec=env WINEPREFIX="/path/to/.wine" wine c:\\\\windows\\\\command\\\\start.exe /Unix /path/to/.wine/dosdevices/c:/users/Public/Рабочий\\ стол/appname.lnkDan dexsolusi berfungsi dengan baik.
MarSoft

27

Sementara OP tidak bertanya tentang KDE, bagi siapa pun yang menjalankan KDE, perintah berikut dapat digunakan:

kioclient exec <path-to-desktop-file>

Di Fedora, ini termasuk dalam kde-runtimerpm.


5
Terpilih karena berfungsi. Tidak perlu menjalankan KDE sama sekali, selama Anda menginstal program ini.
basic6

Apakah ada cara untuk menghentikan ini? Saya telah mengkompilasi pemain clementine, yang memiliki bug yang terjadi hanya meluncurkan melalui file .desktop (dengan plasma-shell). Dan saya tidak tahu, bagaimana cara mendapatkan log output log di mana saja.
Kwaadpepper

@Kwaadpepper Anda dapat menggunakan file .desktop Anda untuk meluncurkan skrip shell, yang secara internal menjalankan perintah Anda dan mengalihkan output ke file.
Raman

Saya tidak menemukan kioclient dalam paket KDE untuk Arch Linux saat ini. Namun, peluncuran gtk bekerja di bawah KDE untuk saya.
MountainX

15

Anda bisa menggunakan dex .

dex foo.desktop

2
IMHO ini jawaban yang tepat: Satu alat, satu panggilan dengan hanya file sebagai parameter. Itulah yang saya cari, juga untuk menguji .desktopfile tulisan tangan . Dan itu bisa membuat .desktopfile juga, yay! :-)
Axel Beckert

Sempurna! Jika Anda menambahkan file .desktop yang menggunakan dex gist.github.com/stuaxo/4169fc1342c496b7c8f7999188f2f242 ke / usr / share / aplikasi / Anda akan dapat meluncurkan file desktop di filemanager tanpa mereka membuka di gedit secara default juga.
Stuart Axon

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

tampaknya bekerja di rilis 13.10, jika exo-utils diinstal (seperti halnya dengan Xubuntu).


Ya, baru saja mengujinya di Ubuntu Studio 14.04. BTW. xdg-open dan gvfs-open bekerja di sana juga.
jarno

Bekerja di 15 juga
Jonathan

Menggunakan Debian dengan xfce. Bagus sekali!
king_julien

Bekerja untuk saya di Ubuntu 14.04
Tyler Collier

8

Tambahan untuk jawaban Hamish.

Dengan skrip deskopen, Anda dapat menggunakan referensi sebagai skrip shebang dalam file .desktop , karena karakter komentarnya masih #. Artinya, letakkan ini sebagai baris pertama dari file .desktop :

#!/usr/bin/env deskopen

Kemudian tandai file .desktop sebagai yang dapat dieksekusi (mis. Dengan a chmod +x whatever.desktop), dan kemudian Anda bisa

path/to/whatever.desktop

dan voila - Aplikasi akan terbuka! (Lengkap dengan file ikon yang saya tentukan, meskipun saya tidak tahu caranya.)

Sekarang, jika Anda juga ingin deskopen melewati parameter baris perintah apa pun, Anda bisa menggunakan versi yang sedikit dimodifikasi ini:

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

Sebagai tambahan, saya mencoba menggunakan "#{@:2}"bukannya shift, tetapi terus memberi saya 'substitusi buruk' ...


Saya tahu ini adalah komentar yang lebih tepat untuk jawaban Hamish, tapi saya pengguna baru dan tidak diizinkan untuk berkomentar. Baiklah!
pabst

Jika Anda memiliki reputasi, tindakan yang paling tepat adalah mengedit jawaban itu.
Flimm

Seperti itu, siapa pun dapat menyarankan pengeditan, bahkan pengguna yang belum masuk! Bagaimanapun juga bukan masalah besar.
Flimm

1
Ini adalah jawaban dengan sendirinya, tidak masalah.
Bruno Pereira

Anda bisa menggunakan "${@:1}"alih-alih shift, tapi itu membutuhkan bashalih-alih shdi #!shebang Anda . IMHO pendekatan pergeseran asli Anda lebih sederhana dan lebih baik
MestreLion

6

Saat ini tidak ada aplikasi yang melakukan apa yang Anda jelaskan di arsip Ubuntu. Ada beberapa upaya yang sedang berlangsung untuk menciptakan solusi umum untuk menyediakan integrasi untuk lingkungan desktop (seperti openbox) yang tidak sesuai dengan spesifikasi XDG ini.

Arch Linux sedang mengerjakan implementasi xdg-autostart berdasarkan pustaka python-xdg. Dari apa yang dapat saya temukan, ini tampaknya belum sepenuhnya lengkap, tetapi memiliki beberapa laporan keberhasilan.

Ada juga implementasi C ++ dari xdg-autostart di gitorious (http://gitorious.org/xdg-autostart/) yang kemungkinan akan mendapat manfaat dari penggunaan yang lebih luas.

Jika salah satu solusi bekerja untuk Anda, harap pertimbangkan untuk mengirimkan karya yang diperlukan untuk dimasukkan dalam Debian atau Ubuntu.

Untuk menggunakan salah satu alat dengan openstart, Anda akan menyebutnya di /etc/xdg/openbox/autostart.sh (jika saya membaca dokumentasi openbox dengan benar). Jika ini tidak berhasil, Anda mungkin dapat menyebutnya di salah satu skrip inisialisasi sesi kotak terbuka.


Bukan apa yang ingin saya dengar, terima kasih atas informasinya
enzotib

6

Saya tidak memiliki solusi segera yang memenuhi persyaratan untuk "menggunakan perintah standar" , tetapi jika Anda memang ingin mem-parsing .desktopfile - file minimal atau ingin membuat alias Bash, maka yang berikut ini akan berfungsi:

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

pendekatan lain yang mungkin menarik, adalah membuat binfmt-miscmetode tingkat kernel dari kecocokan pada .desktopfile (lihat grep -r . /proc/sys/fs/binfmt_misc/pola-pola yang saat ini Anda aktifkan).

Pada akhir hari, sesuatu di suatu tempat harus mengurai .desktopfile, itu hanya pertanyaan tentang bagaimana "standar / standar" itu.


Terima kasih, menarik. Sebagai "standar" yang saya maksudkan adalah sesuatu yang disediakan oleh DE dan sesuai dengan freedesktop.org.
enzotib

Suara positif untuk awkdaripada rantai greps dan seds.
jmtd

Suara positif, meskipun tidak bekerja (atau lebih baik menempatkan - bekerja terlalu banyak) jika Anda memiliki Exec=baris
ultiple

2

Saya mengambil skrip dari jawaban Carlo di atas, dan berupaya memperbaikinya untuk penggunaan desktop saya sendiri.

Versi skrip ini akan memungkinkan Anda untuk menjalankan aplikasi apa pun seolah-olah Anda memasukkannya di HUD, asalkan itu kemungkinan akan menjadi hasil pertama. Ini juga memungkinkan Anda menyampaikan argumen file untuk file .desktop yang tidak mendukung 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:
        # If it's a file, do that first.
            launcher = Gio.DesktopAppInfo.new_from_filename(args.appName)
        except TypeError:
            print "'" + args.appName + "' is not a .desktop file"
            sys.exit(-1)
    # If it's a .desktop file in the DB, try using that
    if launcher is None and args.appName.endswith('.desktop'):
        try:
            launcher = Gio.DesktopAppInfo.new(args.appName)
        except TypeError: pass

    if launcher is None:
        # Search for the app by the text given
        launcher = find_app(args.appName)

    if launcher is None:
        print "No app named " + args.appName + " could be found"
        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="Launch a .desktop file or application")
    argParser.add_argument("appName", 
        help="the name of any application, a desktop file's basename, or a concrete path to a desktop file", 
        action='store'
    )
    argParser.add_argument("uris", 
        nargs='*', 
        help="Files or URIs to pass to the application"
    )
    args = argParser.parse_args()
    main(args)

1

Ketika mencoba untuk menguji file-file ini, saya menemukan cara paling sederhana untuk memeriksa bahwa DM atau manajer sesi akan melakukan apa yang saya harapkan adalah membuka direktori di sekitarnya di browser folder UI dan kemudian klik dua kali untuk membukanya.

Jika Anda berada di baris perintah: gvfs-open .atau gnome-open .akan membukanya di browser folder yang dikonfigurasi.

Hal sed tidak akan mencerminkan perilaku DM, termasuk hal-hal fiddly seperti melarikan diri dan mengutip di mana Anda benar-benar tidak ingin perilaku alternatif. Ini bukan baris perintah, tetapi memang memvalidasi hal-hal. Saya juga menemukan pengaturan Terminal=trueberguna untuk debugging.


Terminal segera menghilang, saya tidak punya waktu untuk melihat pesan ketika menggunakan Terminal = true: s
gouessej

1

Ini SO jawabannya adalah apa yang membuat jelas bagi saya: jangan mencoba untuk menjalankan file desktop mengeksekusi file tersebut menunjuk pada desktop file.

Sebagai contoh, jalankan / home / jsmith/Desktop/x11vnc.sh

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

1

(Disusun dari berbagai jawaban lain di sini)

Bergantung pada sistem Anda, dan berbagai bug yang mungkin atau mungkin tidak ada pada sistem Anda, coba yang berikut sampai salah satu dari mereka bekerja:

  1. xdg-open program_name.desktop
  2. exo-open program_name.desktop
  3. gtk-launch program_name.desktop
  4. kioclient exec program_name.desktop
  5. dex program_name.desktop

Perhatikan bahwa pada sistem Ubuntu, peluncur desktop "menu mulai" Anda tersedia di /usr/share/applications/.

Sebagai contoh, untuk menunjukkan perintah mana di atas yang berfungsi atau tidak bekerja pada sistem Ubuntu 14.04 saya, inilah hasil dari panggilan berikut untuk saya:

  1. xdg-open /usr/share/applications/eclipse_for_cpp.desktop # Gagal karena bug (mencoba agar saya menyimpan file .desktop ini)
  2. exo-open /usr/share/applications/eclipse_for_cpp.desktop # Bekerja
  3. gtk-launch /usr/share/applications/eclipse_for_cpp.desktop # Gagal dengan "gtk-launch: no application like"
  4. kioclient exec /usr/share/applications/eclipse_for_cpp.desktop # Bekerja
  5. dex /usr/share/applications/eclipse_for_cpp.desktop# Gagal, & sudo apt install dextidak dapat menemukan paket dex

0

Pastikan skrip yang ditunjukkan file desktop Anda juga dapat dieksekusi.

Jika masih tidak berhasil. Buat file desktop dapat dijalankan di terminal dengan mengubah Terminal=true, dan memasukkannya ke dalam skrip bash. Jalankan skrip untuk menangkap output kesalahan. Ubah kembali ketika kesalahan diperbaiki.


0

Jawaban Hamish sangat bagus, tetapi saya ingin menyarankan alternatif yang lebih sederhana, dengan sedikit melibatkan:

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

Dalam hal ini, awkcari baris yang dimulai dengan Exec, dan kemudian kita cukup mencetak bidang setelah baris itu, menggunakan untuk loop dan =kita mencetak bidang 2, yaitu, apa pun yang muncul setelah bidang itu. Kurung keriting di ujung perintah $(...),, adalah substitusi parameter, sehingga shell akan mengeksekusi perintah awk apa pun; dalam hal ini, ia mengembalikan perintah aktual yang datang setelah Exec=.

Dalam beberapa kasus yang jarang terjadi mungkin ada lebih dari satu =tanda, yang masih memungkinkan. Untuk itu, saya sarankan

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

Nice, awkand Serg =)
AB

Dan terkadang, ada TryExec, mungkin Anda harus memeriksa perintah ke-2 Anda =)
AB

@ AB Hehe, awkadalah senjata pilihan saya dalam hal pemrosesan teks. Selain itu, sintaksinya dekat C. Oh, dan sudah menambahkan TryExecbagian ^ _ ^
Sergiy Kolodyazhnyy

Anda memiliki +1 saya =)
AB

Tapi apa tentang %f, %u, %Uatau sesuatu seperti ini di belakang perintah?
AB
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.