在终端中运行一个 .desktop 文件

从我所了解的情况来看,.desktop文件是允许自定义应用程序设置的快捷方式。例如,在我的/usr/share/applications/文件夹中有很多这样的文件。
如果我在nautilus中打开该文件夹,只需双击关联的文件,如双击firefox.desktop就可以运行Firefox。然而,我找不到通过终端执行相同操作的方法。
如果我执行gnome-open foo.desktop,它只会将foo.desktop作为文本文件打开。如果我将其设置为可执行并在bash中运行,它会失败(这是预期的,因为它显然不是bash脚本)。 编辑:执行exec /fullpath/foo.desktop会显示“权限被拒绝”的消息,即使我将所有权更改为自己也是如此。如果我将其设置为可执行并执行相同的命令,我正在使用的终端选项卡会直接关闭(我猜测是崩溃)。最后,如果我执行sudo exec /fullpath/foo.desktop,会出现“sudo: exec: command not found”的错误。

这是我的问题,我如何在终端中运行一个 foo.desktop 文件?


6你的exec失败的原因是因为exec会用指定的进程替换当前正在运行的进程,所以你试图用编译好的二进制文件来替换你的shell,从而运行桌面。你无法使用sudo exec是因为它是一个shell内置命令,而不是一个二进制命令。 - Daenyth
有趣,我想知道为什么会导致标签关闭。 - Malabarba
1相关链接:Gnome .desktop文件的Hashbang - ændrük
我明白了,他们最终会解析.desktop文件。无论如何,还是谢谢你提供的链接。 - enzotib
直接和经过测试的答案是2019年提供的6个选项:https://askubuntu.com/a/1114798/795299 - alchemy
20个回答

gtk-launch

对于任何支持gtk-launch的最新版本Ubuntu,只需简单地执行以下操作:

gtk-launch <file>

<file>.desktop 文件的名称,可以包含或不包含 .desktop 后缀。名称不能包含完整路径。

.desktop 文件必须位于 /usr/share/applications/usr/local/share/applications~/.local/share/applications 中。

因此,gtk-launch foo 打开 /usr/share/applications/foo.desktop(或位于其他允许目录中的 foo.desktop)。

来自 gtk-launch 文档

gtk-launch 使用给定的名称启动应用程序。除非另有指定,否则在默认显示器上使用适当的启动通知启动应用程序。

gtk-launch 至少需要一个参数,即要启动的应用程序的名称。该名称应与应用程序桌面文件名匹配,如存储在 /usr/share/application 中,可以包含或不包含 '.desktop' 后缀

可从终端或Alt + F2使用(Alt + F2将命令存储在历史记录中,因此很容易访问)。

gtk-launch firefox.desktop /.local/share/applications/会启动 Firefox,并为我打开目录/.local/share/applications/。看起来,如果你是正确的,Firefox不应该将包含.desktop文件的目录作为参数传递。实际上,传递给 gtk-launch 的目录不应该用于定位包含 .desktop 文件的目录(事实上也没有这样做)。 - Croad Langshan
这对我在Arch Linux上也有效。其他的回答都不令人满意,但这个不错。:-) 即使我在运行KDE,它也能正常工作。 - MountainX
9在Ubuntu 18.10上,没有任何版本适用于我。每次都会抱怨应用程序不存在,无论我是否在包含桌面文件的文件夹中,无论我是否包含.desktop扩展名,以及是否单独命名目录。 - Joseph Garvin
@ Joseph,我没有添加关于提供路径的部分,可能是其他人添加的,而且可能是错误的。如注所述,.desktop 文件需要位于应用程序文件夹中。(/usr/share/applications、/usr/local/share/applications 或 ~/.local/share/applications) - doug
1这真是毫无意义。唯一的实际用途就是启动用户自制的.desktop启动器。如果你的应用程序在/usr/local/share/applications目录下,你只需在终端中输入应用程序的名称即可。 - tatsu
2@JosephGarvin 好的,我弄明白了,是在Ubuntu 18.10上使用gtk-launch MYCUSTOMAPP.desktop命令,不需要路径。 - tatsu
文件可以位于 https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html 中指定的任何数据目录中。 - jarno
谢谢你这个。我一直在寻找一种绕过此问题的方法,同时仍然能够使用.desktop文件(用于处理像%U这样的内容),而gtk-launch完美地解决了这个问题。我确实从那里下载并安装了修补过的Nautilus版本,但能够找到一个不需要降级核心系统(就GNOME而言)应用程序的解决方案真是太好了。 - FallenWarrior
这似乎对~/.local/share/applications/目录中的文件无效。 - geekley
啊!在Kubuntu 20.04上,kioclient5 exec ~/.local/share/applications/myprogram.desktop对我有效。如果你使用的是KDE,请参考下面的答案 - geekley
这是一个特定于Gnome的答案,如果你的桌面环境不是GNOME,它将强制你加载不需要的库来使其工作,我强烈建议使用@Carlo Pellegrini的答案并使用glib gio。 - Lyoneel

答案应该是
xdg-open program_name.desktop

但由于一个错误在这里上游,已于2020年12月9日关闭),这个功能不再起作用。

在GNOME上,你可以使用gnome-open命令,它又会调用xdg-open命令,而这个命令存在一个bug。 - Richard Holloway
9哇,这个还是个bug,xdg有很多进展。exo-open被列为解决方法,它也可以打开gedit。:( - Drew
1@RichardHolloway:gnome-open并不调用xdg-open,正好相反!因此,问题出在gvfs-opengnome-open的继任者)上。 - MestreLion
21不再工作。它从未工作过!xdg-open通过 mimetype 关联起作用,而 .desktop 文件与文本编辑器相关联,因为它们是文本的子类。 - MestreLion
21这太愚蠢了(没有明智的方法从终端运行桌面文件)。 - Sam Watkins
1这个bug还在啊? - Noitidart
2在Arch Linux上对我有效,但可能是一个Ubuntu特定的错误。 - Victor
在Ubuntu 16.04上对我来说没问题。 - gerardw
1在Ubuntu 16.04上对我不起作用。只是在gedit中打开了.desktop文件。 - wisbucky
3这在我目前使用的Arch Linux上不起作用。xdg-open program_name.desktop会在文本编辑器中打开桌面文件。 - MountainX
相同的 Ubuntu 18.10 仍然打开 Gedit。 - tatsu
1在18.04版本的Xubuntu中对我有效。根据xdg-open和xdg-mime的帮助输出,它不应该有效。 - itmuckel
在Ubuntu上,可以单独安装exo-open而不需要引入整个XFCE吗?我问这个问题是因为在Opensuse中,exo-tools是一个独立的软件包,只对XFCE有最小的依赖(我认为只有一个核心库)。 - shadowtalker
如果这对你有用的话,很可能是你将桌面文件与某个启动器关联起来了,而不是一个文本编辑器。 - xuhdev
在Linux Mint 20.3上对我来说没问题。 - bobismijnnaam

现代答案

gtk-launch <app-name> - 其中<app-name>.desktop文件的文件名,可以带有或不带有.desktop扩展名。

更多详细信息请参见此线程上的另一个答案我从那个答案中获取了这些信息。

已弃用的Shell工具答案

很久以前写的 - 请参阅下面的评论,了解为什么这种方法对许多桌面文件无效。

运行的命令包含在桌面文件中,以Exec=开头,因此您可以提取并运行它:

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

拆解一下
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

你可以把这个放在一个文件里,比如说~/bin/deskopen,文件的内容如下:
#!/bin/sh
$(grep '^Exec' $1 | tail -1 | sed 's/^Exec=//' | sed 's/%.//' \
| sed 's/^"//g' | sed 's/" *$//g') &

然后将其设置为可执行文件
chmod +x ~/bin/deskopen

然后你可以做,例如。
deskopen /usr/share/applications/ubuntu-about.desktop

参数(%u%F等)的详细信息可以在这里找到。但是在命令行启动时,它们都不相关。

这是目前最好的结果,但有时会产生不可取的行为。每当"Exec="行带有像%u或%i这样的参数时就会发生这种情况。Bash试图将该字符串作为普通参数传递。例如,执行grep '^Exec' firefox.desktop | sed 's/^Exec=//'会打开一个加载www.%u.com的 Firefox 标签页。 - Malabarba
目前,我已经添加了第二个 sed 命令来删除任何参数。但是我认为可能有一种更加“自然”的运行方式。 - Malabarba
我已经更新了我的答案,加上了额外的sed命令 - 我忘记了桌面文件可能有参数。 - Hamish Downer
在“grep”之后,您应该在管道中添加一个“tail -1”,因为“Exec=”可能会出现多次,而且之后,只有最后一次出现才应该被执行。 - daisy
@warl0ck:感谢你的建议 - 我已经根据你的建议更新了答案。 - Hamish Downer
15-1:这可能适用于简单的.desktop文件,但它忽略了Path=TryExec=等条目,这可能会影响执行。如果文件包含桌面操作("quicklists"),它还会执行错误的Exec= - MestreLion
应用程序没有显示图标。这是预期的行为还是我在某个文件中出了问题? - Lucio
这对我没用。似乎所有路径都被双引号括起来了。Carlo的脚本有效。 - Albert
这在 vlc.desktop 方面给了我一些问题,它有一个形式为 --started-from-file 的选项。我添加了另一个管道来去除它:sed 's/-.*//g'... 我几乎不知道如何使用 sed,所以我不知道这是否没有问题。 - Samuel
黑客式的黑客是粗糙的 - 需要一种能让桌面运行它的解决方案。 - nhed
这个答案在执行字符串以双引号结束时失败。它删除了最后一个引号,但保留了第一个引号。例如:Exec=su-to-root -c "/usr/local/bin/ddm-mx -i nvidia" 的结果是:su-to-root -c "/usr/local/bin/ddm-mx -i nvidia - Bob C
@BobC 是的,只需将最后两个seds更改为: sed 's/^"\(.*\)"$/\1/g' - knezi
我喜欢你的“已弃用的shell工具答案”,虽然对于所有情况来说并不完美,但适用于大多数桌面文件。因此,我给你的答案点了赞,并且也将那个脚本放入了我的总结答案中(链接:https://askubuntu.com/a/1114798/327339)。 - Gabriel Staples
对于那些通过谷歌搜索找到答案并希望启动桌面文件的人来说,对于gtk-launch命令,文件必须位于特定的文件夹中。请参考https://unix.stackexchange.com/questions/393079/gtk-launch-only-works-when-present-working-directory-is-desktop - Alex Martian

虽然 OP 没有询问 KDE,但对于任何运行 KDE 的人,可以使用以下命令:

kioclient exec <path-to-desktop-file>

在 Fedora 上,这包含在 kde-runtime rpm 中。在 Arch 上,它位于 kde-cli-tools(HT:@Aron Cederholm)。


9因为它有效,所以点赞了。完全不需要运行KDE,只要安装了这个程序就可以了。 - basic6
有没有办法获取这个的标准输出?我已经编译了Clementine播放器,它有一个只在通过.desktop文件(使用plasma-shell)启动时出现的错误。而且我无法弄清楚如何在任何地方记录输出日志。 - Kwaadpepper
@Kwaadpepper 你可以使用你的 .desktop 文件来启动一个 shell 脚本,该脚本内部运行你的命令并将输出重定向到一个文件中。 - Raman
目前在Arch Linux的KDE软件包中,我找不到kioclient。然而,在KDE下,gtk-launch对我来说是可用的。 - MountainX
3在Kubuntu 20.04上,kioclient5 exec ~/.local/share/applications/myprogram.desktop 对我起了作用。 - geekley
@geekley 它在KDE Neon 5.22.4(Ubuntu 20.04)上也可以运行。 - RatajS
@MountainX,它位于kde-cli-tools软件包中。 - Xyz

自从glib 2.67.2版本以后,有一个gio launch命令可以这样使用:
gio launch ./foo.desktop

对于旧版本,我有一个快速解决方法(从nautilus源代码中获取灵感)。虽然有点复杂,但在Ubuntu 12.10上可以完美运行,在Unity启动器上添加了一个有意义的图标(不再是“?”)。
首先,我编写了一个使用Gio的Python脚本,并将其保存为~/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)

脚本需要具有可执行权限,所以我在终端中运行了以下命令:
chmod +x ~/bin/run-desktop

然后我在`~/.local/share/applications/run-desktop.desktop`上创建了相对的`.desktop`入口:
[Desktop Entry]
Version=1.0
Name=run-desktop
Exec=run-desktop %U
MimeType=application/x-desktop
Terminal=false
Type=Application

最后,我将该条目关联为默认处理程序,在~/.local/share/applications/mimeapps.list文件中的[Default Applications]部分如下所示:
[Default Applications]
....
application/x-desktop=run-desktop.desktop

现在:
  • xdg-open something.desktop按预期工作
  • #!/usr/bin/xdg-open 可执行桌面条目顶部的hashbang也可以正常工作

1这个方法比Hamish Downer的回答更好,因为它可以正确处理多个Exec=行和命令中的%参数。 - Flimm
4谢谢代码 - 我在Lucid上,我将它保存为/usr/bin/xdg-openpy,并且给了它一个chmod +x权限 - 然后使用了launcher.launch([],context)而不是...None,context)(因为出现了"TypeError: argument 1: Must be sequence, not NoneType")。现在,在命令行中可以通过xdg-openpy app.desktop运行(双击app.desktop时也一切正常),如果我尝试在终端中调用xdg-open并按下Tab键,它会提醒我。干杯! - sdaau
5+1。这是唯一一个不需要手动解析“.desktop”文件的答案,因此它是最明智(和安全)的方法。还使用现代的“gi.repository”而不是已弃用的“pygtk”,非常好! :) - MestreLion
2实际上,这是关于Carlo Pellegrini的回答的问题。我是新手,请纠正我如果有更好的放置方式。脚本运行得非常好,但我在Unity启动器上得到的图标不是.desktop文件中定义的图标,而是“Exec”命令的默认图标。有什么想法吗? - Ingo Leonhardt
@IngoLeonhardt 你有找到解决方法吗?我也在尝试将图标设置为.desktop文件的图标。 - Noitidart
很遗憾,我已经学会了接受它,并且没有再做任何努力。 - Ingo Leonhardt
谢谢@IngoLeonhardt的回复!我实际上在Gio的文档中找到了很多内容,并且有很多关于icon的内容(例如gdk_app_launch_context_set_icon_name),我认为这是非常可能的!你有没有研究过Gio的文档?我正在阅读这里的代码:https://github.com/mathitme/nautilus/blob/2944be953ef54717bb24968b0eebe468c9705db4/libnautilus-private/nautilus-program-choosing.c#L142 - Noitidart
@noitidart 我的关注点是启动特别参数化的xterms,并使用不同的图标来区分它们。所以我没有看过C代码。不过,如果你找到了什么东西,我会很高兴你能告诉我。 - Ingo Leonhardt
一定会给你及时更新 @IngoLeonhardt :) 我非常需要自定义图标的解决方案 :) - Noitidart
嘿 @IngoLeonhardt,我找到了用于实现此功能的C代码,并且它确实可以使用自定义图标启动!这是Firefox的js-ctypes代码。要运行它,你可以参考这个YouTube视频:https://www.youtube.com/watch?v=Rzgf7-I5QPg 你确定没有使用.desktop文件的图标吗? - Noitidart
@IngoLeonhardt 我在 Ubuntu 14.04 上测试了启动 .desktop 文件,它成功启动并且自定义图标在任何地方都显示出来。但在 Mint Cinnamon 17.1 上,如果双击 .desktop 文件或者使用 Gio 启动它,它不会获取 .desktop 文件的图标。我在考虑使用 gdk_app_launch_context_set_icon_name 和 Gio launch_uris 进行研究,也许这样可以实现获取图标的功能,有什么建议吗? - Noitidart
@Noitidart 目前不行(时间也不太多)。但我已经将我的 run-desktop 更新到这个答案的当前版本,但 gnome-terminal 仍然使用它的默认图标启动,而不是 .desktop 文件中指定的图标(Ubuntu 14.04 也是如此)。 - Ingo Leonhardt
1@Noitidart 写的最后一个答案让我去谷歌了一下,我找到了这个链接:that。虽然还没看过,但也许会有帮助。 - Ingo Leonhardt
xseticon看起来很有趣,它一定是一个自定义函数,用于设置_NET_WM_ICON - Noitidart
@IngoLeonhardt 是的,他们是通过XChangeProperty来实现的。我下载了这个文件:https://gist.github.com/Noitidart/64ad2edbda32627b684f - Noitidart

正确的方法

如果可用,您应该真正使用gtk-launch。它通常是软件包libgtk-3-bin的一部分(这可能因发行版而异)。

gtk-launch的使用方法如下:

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

请注意,gtk-launch需要安装.desktop文件(即位于/usr/share/applications~/.local/share/applications)。
为了解决这个问题,我们可以使用一个巧妙的小Bash函数,在启动之前临时安装所需的.desktop文件。在安装.desktop文件的“正确”方法是通过desktop-file-install,但我将忽略它。
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

    )

}

你可以这样使用它(如果需要,还可以传递其他参数或URI):
launch PATH [URI...]
launch ./path/to/shortcut.desktop

手动替代方案

如果你想手动解析和执行一个 .desktop 文件,你可以使用以下的 awk 命令来实现:

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

如果你想把 awk 命令当作一个全能脚本来使用,我们甚至可以在找不到 Exec 命令的情况下显示错误消息并退出,并返回 1 的返回码:
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}}'

上述命令将会:
  1. 查找以 Exec= 开头的行
  2. 删除 Exec=
  3. 删除任何 Exec 变量(例如 %f, %u, %U)。根据规范,可以用位置参数替换这些变量,但这样做会给问题增加相当复杂性。请参考最新的桌面入口规范
  4. 执行命令
  5. 立即以适当的退出码退出(以避免执行多个 Exec 行)

注意,此 AWK 脚本解决了一些其他答案可能没有正确处理的特殊情况。具体来说,该命令会删除多个 Exec 变量(同时确保不删除 % 符号),只会执行单个 Exec 行命令,并且即使 Exec 行命令中包含一个或多个等号(例如 script.py --profile=name),也会按预期运行。

只是还有一些其他要注意的地方... 根据规范,TryExec 是:

磁盘上可执行文件的路径,用于确定程序是否安装。如果路径不是绝对路径,则会在 $PATH 环境变量中查找该文件。如果文件不存在或者不可执行,该条目可能会被忽略(例如,在菜单中不使用)。

考虑到这一点,执行它的值就没有意义了。
一些其他的问题是路径终端路径包括运行程序的工作目录。 终端是一个布尔值,表示程序是否在终端窗口中运行。这些都可以解决,但没有必要重新发明轮子,因为已经有了规范的实现。如果您确实想要实现路径,请记住system()会生成一个子进程,所以您不能通过像system("cd \047" working_directory "\047"); system(command)这样的方式来更改工作目录。不过,您可以尝试像system("cd \047" working_directory "\047 && " command)这样的方式。注意\047是单引号(这样命令就不会在带有空格的路径上中断)。

Python替代方案

我从Carlo 这里那里借鉴了一个方法,他建议创建一个使用gi模块的Python脚本。以下是一种在不创建文件和担心I/O的情况下从shell执行相同代码的最简方式。

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

}

然后按照以下方式执行启动器函数:
launch ./path/to/shortcut.desktop

请注意,使用URI是可选的。此外,没有进行错误检查,所以如果您希望脚本具有耐久性,在使用之前,请确保启动器存在且可读。

但是awk命令很好。因此+1。 - A.B.
在这个上下文中,URI是什么?我在一个任意文件夹中有一个桌面文件。我该如何毫不费力地运行gtk-launch,而无需将其包装在其他脚本中?这真让人抓狂。 - Joseph Garvin
这个 awk 解决方案在命令中有双重转义的空格或反斜杠时无法正常工作。它会在这种情况下出错:Exec=env WINEPREFIX="/path/to/.wine" wine c:\\\\windows\\\\command\\\\start.exe /Unix /path/to/.wine/dosdevices/c:/users/Public/Рабочий\\ стол/appname.lnk,而 dex 解决方案可以正常工作。 - MarSoft
我喜欢Python的解决方案。不需要进行字符串操作,从而避免了一些Shell参数的陷阱。 - Radu C

你可以使用dex:生成和执行应用程序类型的.desktop文件。
桌面入口执行实现了Freedesktop.org自启动规范,与任何桌面或窗口管理器环境无关。 应用程序可以根据.desktop文件中广告的桌面环境进行过滤。
安装dex:
sudo apt install dex

运行文件:
dex foo.desktop

4依我之见,这正是正确的答案:一个工具,只需一个参数——文件名。这正是我所寻找的,用来测试手写的.desktop文件。而且它还可以创建.desktop文件,太棒了!:-) - Axel Beckert
1完美!如果您添加一个使用dex的.desktop文件 https://gist.github.com/stuaxo/4169fc1342c496b7c8f7999188f2f242 到/usr/share/applications/,您将能够在文件管理器中启动桌面文件,而不会默认在gedit中打开它们。 - Stuart Axon
$ dex chromium.desktop 返回:文件不存在:/home/$USER/chromium.desktop。这个解决方案不太便携,否则你只能使用$ dex /usr/share/applications/chromium.desktopgtk-launch可以在没有完整路径的情况下工作。 - thiagowfx

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

似乎在13.10版本中运行良好,如果安装了exo-utils(就像Xubuntu的情况一样)。

是的,我刚在Ubuntu Studio 14.04上测试过了。顺便说一句,xdg-open和gvfs-open也可以在那里使用。 - jarno

(根据这里的其他答案编写)
根据您的系统以及可能存在或不存在的各种错误,请尝试以下方法,直到其中一个生效为止:
  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
  6. 或者,这里是@Hamish Downer提供的命令,它会在 *.desktop 文件中使用 grep 搜索包含要执行的命令的 Exec= 行,然后删除我们不需要的该行的部分,并执行该命令。这是一个编写良好且对大多数桌面文件有效的方法。详细解释请参见 他的回答
    # 在后台执行 filename.desktop 中的 `Exec=` 命令
    $(grep '^Exec' filename.desktop | tail -1 | sed 's/^Exec=//' \
    | sed 's/%.//' | sed 's/^"//g' | sed 's/" *$//g') &
    
    # 或者,删除末尾的 `&` 以在前台执行,这样您可以看到运行命令的输出
    $(grep '^Exec' filename.desktop | tail -1 | sed 's/^Exec=//' \
    | sed 's/%.//' | sed 's/^"//g' | sed 's/" *$//g')
    
请注意,在Ubuntu系统上,您的“开始菜单”桌面启动器位于/usr/share/applications/目录下。
例如,为了展示上述命令在我的Ubuntu 14.04系统上哪些有效或无效,以下是我进行的调用的结果:
  1. xdg-open /usr/share/applications/eclipse_for_cpp.desktop # 由于错误而失败(尝试让我保存这个 .desktop 文件)
  2. exo-open /usr/share/applications/eclipse_for_cpp.desktop # 成功
  3. gtk-launch /usr/share/applications/eclipse_for_cpp.desktop # 失败,显示“gtk-launch: 没有这个应用程序”
  4. kioclient exec /usr/share/applications/eclipse_for_cpp.desktop # 成功
  5. dex /usr/share/applications/eclipse_for_cpp.desktop # 失败,并且 sudo apt install dex 找不到 dex 软件包
  6. $(grep '^Exec' /usr/share/applications/eclipse_for_cpp.desktop | tail -1 | sed 's/^Exec=//' | sed 's/%.//' | sed 's/^"//g' | sed 's/" *$//g') & # 成功

Hamish的回答补充。

根据deskopen脚本,你可以将其作为.desktop文件中的shebang行的引用,因为注释字符仍然是#。也就是说,将以下内容作为.desktop文件的第一行:

#!/usr/bin/env deskopen

然后将.desktop文件标记为可执行文件(例如,使用chmod +x whatever.desktop命令),然后您就可以。
path/to/whatever.desktop

然后,就这样——应用程序将会打开!(包括我指定的图标文件,尽管我不知道如何操作。)

现在,如果你还想让deskopen传递任何命令行参数,你可以使用这个稍微修改过的版本:

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

顺便说一下,我尝试使用"#{@:2}"而不是shift,但它一直给我报错'bad substitution'...

我知道这更适合作为对Hamish回答的评论,但我是一个新用户,不能发表评论。唉! - pabst
如果你有声誉的话,最合适的行动就是实际上编辑那个答案。 - Flimm
不用在意,任何人都可以提出建议修改,甚至没有登录的用户也可以!这根本没什么大不了的。 - Flimm
你可以使用${@:1}代替shift,但这需要在你的#! shebang中使用bash而不是sh。我认为你最初的shift方法更简单、更好。 - MestreLion
我按照你说的做了,我创建了外壳,并在我的桌面文件中添加了shebang在顶部。但是它没有用我在.desktop文件上设置的图标打开:( 如果你方便的话,我可以分享一个屏幕录像来展示我的情况 :) - Noitidart