AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 5172
Accepted
Malabarba
Malabarba
Asked: 2010-10-05 05:58:47 +0800 CST2010-10-05 05:58:47 +0800 CST 2010-10-05 05:58:47 +0800 CST

在终端中运行 .desktop 文件

  • 772

据我所知,.desktop文件是允许自定义应用程序设置的快捷方式。例如,我的/usr/share/applications/文件夹中有很多。

如果我在 中打开该文件夹nautilus,只需双击其关联文件即可运行这些应用程序,例如双击firefox.desktop运行 Firefox。但是,我找不到通过终端做同样事情的方法。

如果我这样做gnome-open foo.desktop,它只是foo.desktop作为文本文件打开。如果我让它可执行然后在 bash 中运行它,它就会失败(这是预期的,它显然不是 bash 脚本)。
编辑:即使我将所有权更改为自己,这样做也会exec /fullpath/foo.desktop给我一个信息。Permission denied如果我制作可执行文件并执行相同的命令,我正在使用的终端选项卡就会关闭(我猜它会崩溃)。最后,如果我这样做sudo exec /fullpath/foo.desktop,我会收到错误报告sudo: exec: command not found。

这是我的问题,如何foo.desktop从终端运行文件?

shortcuts command-line .desktop
  • 20 20 个回答
  • 286513 Views

20 个回答

  • Voted
  1. doug
    2013-12-03T14:32:15+08:002013-12-03T14:32:15+08:00

    gtk-启动

    使用任何支持的最新 Ubuntugtk-launch只需简单地

    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将命令存储在历史记录中,以便轻松访问)。

    • 132
  2. Richard Holloway
    2010-10-05T07:28:56+08:002010-10-05T07:28:56+08:00

    答案应该是

    xdg-open program_name.desktop
    

    但由于一个错误(此处为上游,于 2020 年 12 月 9 日关闭),这不再有效。

    • 104
  3. Best Answer
    Hamish Downer
    2010-10-05T06:52:31+08:002010-10-05T06:52:31+08:00

    现代答案

    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详细说明。它们都与在命令行启动无关。

    • 84
  4. Raman
    2014-02-24T10:09:11+08:002014-02-24T10:09:11+08:00

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

    kioclient exec <path-to-desktop-file>

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

    • 46
  5. Carlo Pellegrini
    2013-01-12T01:06:17+08:002013-01-12T01:06:17+08:00

    从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
    

    然后我在以下位置创建了相关.desktop条目~/.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
    

    ~/.local/share/applications/mimeapps.list最后,我将条目作为该部分下的默认处理程序关联[Default Applications]为:

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

    现在:

    • xdg-opensomething.desktop 按预期工作
    • #!/usr/bin/xdg-open 可执行桌面条目顶部的 hashbang 也可以
    • 40
  6. Six
    2015-08-22T11:33:42+08:002015-08-22T11:33:42+08:00

    正确的方式

    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)。

    所以为了解决这个问题,我们可以使用一个 hackish 的小 Bash 函数,在启动它之前临时安装所需的.desktop文件。安装.desktop文件的“正确”方法是 via,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. 删除执行=
    3. 删除所有 Exec 变量(例如%f, %u, %U)。可以按照规范的意图将这些替换为位置参数,但这样做会大大增加问题的复杂性。请参阅最新的桌面条目规范。
    4. 执行命令
    5. 立即使用适当的退出代码退出(以免执行多个Exec行)

    请注意,此 AWK 脚本解决了一些边缘情况,这些情况可能会或可能不会被其他一些答案正确解决。具体来说,该命令会删除多个Exec变量(注意不要以其他方式删除 % 符号),只会执行单个Exec行命令,并且即使Exec行命令包含一个或多个等号(例如script.py --profile=name),也会按预期运行。

    只是其他一些警告......根据规范,TryExec是:

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

    考虑到这一点,执行它的价值是没有意义的。

    其他一些问题是Path和Terminal。路径由运行程序的工作目录组成。终端是一个布尔值,指示程序是否在终端窗口中运行。这些都可以解决,但是重新发明轮子没有意义,因为已经有规范的实现。如果您确实想实现Path,请记住它会system()产生一个子进程,因此您不能通过执行类似system("cd \047" working_directory "\047"); system(command). 但是,您大概可以执行类似system("cd \047" working_directory "\047 && " command). 注意 \047 是单引号(因此该命令不会在带有空格的路径上中断)。

    Python 替代方案

    我在这里从 Carlo 那里偷了一个页面,他建议创建一个 Python 脚本来使用gi模块。这是从 shell 执行相同代码而无需创建文件和担心 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
    
    }
    

    然后执行launcher函数如下:

    launch ./path/to/shortcut.desktop
    

    请注意,URI 的使用是可选的。此外,不执行错误检查,因此如果您希望脚本持久,您需要确保启动器存在并且可读(在使用之前)。

    • 39
  7. couac
    2015-01-26T15:17:09+08:002015-01-26T15:17:09+08:00

    你可以使用dex。

    安装 dex:

    sudo apt install dex
    

    用它运行文件:

    dex foo.desktop
    
    • 35
  8. jarno
    2013-12-23T07:45:09+08:002013-12-23T07:45:09+08:00
    exo-open [[path-to-a-desktop-file]...]
    

    如果安装了 exo-utils 似乎可以在 13.10 版本中使用(就像 Xubuntu 的情况一样)。

    • 21
  9. Gabriel Staples
    2019-02-02T10:24:35+08:002019-02-02T10:24:35+08:00

    (从这里的各种其他答案编译)

    根据您的系统以及系统上可能存在或不存在的各种错误,请尝试以下操作,直到其中一个有效:

    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 的命令,它grep在 *.desktop 文件中搜索Exec=包含要执行的命令的行,删除我们不需要的行的部分,然后执行它。它写得很好,适用于大多数桌面文件。请参阅他的答案以获得完整的解释。
      # To execute the `Exec=` cmd from filename.desktop in the background
      $(grep '^Exec' filename.desktop | tail -1 | sed 's/^Exec=//' \
      | sed 's/%.//' | sed 's/^"//g' | sed 's/" *$//g') &
      
      # Or, remove the `&` at the end to execute it in the foreground so you 
      # can see output from running the command too
      $(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: no such application”
    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') &# 工作
    • 12
  10. pabst
    2012-02-10T12:12:22+08:002012-02-10T12:12:22+08:00

    哈米什答案的附录。

    给定 desktopopen 脚本,您可以使用对它的引用作为.desktop文件中的 shebang 行,因为注释字符仍然是#. 也就是说,把这个作为.desktop文件的第一行:

    #!/usr/bin/env deskopen
    

    然后将.desktop文件标记为可执行文件(例如使用 a 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}"而不是shifting,但它一直给我“糟糕的替代”......

    • 9

相关问题

  • 如何从命令行仅安装安全更新?关于如何管理更新的一些提示

  • 如何从命令行刻录双层 dvd iso

  • 如何从命令行判断机器是否需要重新启动?

  • 文件权限如何工作?文件权限用户和组

  • 如何在 Vim 中启用全彩支持?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何安装 .run 文件?

    • 7 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    如何获得 CPU 温度?

    • 21 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Marko Smith

    如何使用命令行将用户添加为新的 sudoer?

    • 7 个回答
  • Marko Smith

    更改文件夹权限和所有权

    • 9 个回答
  • Marko Smith

    你如何重新启动Apache?

    • 13 个回答
  • Marko Smith

    如何卸载软件?

    • 11 个回答
  • Marko Smith

    如何删除 PPA?

    • 26 个回答
  • Martin Hope
    NES 如何启用或禁用服务? 2010-12-30 13:03:32 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    Olivier Lalonde 如何在结束 ssh 会话后保持进程运行? 2010-10-22 04:09:13 +0800 CST
  • Martin Hope
    David B 如何使用命令行将用户添加为新的 sudoer? 2010-10-16 04:02:45 +0800 CST
  • Martin Hope
    Hans 如何删除旧内核版本以清理启动菜单? 2010-08-21 19:37:01 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve