Запуск файла .desktop в терминале

Из того, что я могу собрать, файлы .desktop - это ярлыки, которые позволяют настраивать настройки приложения. Например, у меня их много в папке /usr/share/applications/.

Если я открою эту папку в nautilus, я могу запустить эти приложения, просто дважды щелкнув соответствующий файл, например. двойной щелчок firefox.desktop запускает Firefox. Однако я не могу найти способ сделать то же самое через терминал.

Если я делаю gnome-open foo.desktop, он просто открывает foo.desktop в виде текстового файла. Если я делаю его исполняемым, а затем запускаю его в bash, он просто терпит неудачу (что ожидается, это явно не скрипт bash). EDIT: Выполнение exec /fullpath/foo.desktop дает мне сообщение Permission denied, даже если я перехожу к себе. Если я делаю исполняемый файл и выполняю ту же команду, вкладка терминала, которую я использую, просто закрывается (я предполагаю, что она сработает). Наконец, если я sudo exec /fullpath/foo.desktop, я получаю сообщение об ошибке sudo: exec: command not found.

Это мой вопрос, как я могу запустить файл foo.desktop с терминала?

1
задан 11 September 2015 в 16:51

15 ответов

Ответ должен быть

xdg-open program_name.desktop

Но из-за ошибки это больше не работает.

61
ответ дан 26 May 2018 в 01:13
  • 1
    WoW это все еще ошибка, много прогресса в xdg. exo-open указан как обходной путь, и он также открывает gedit. :( – Drew 17 October 2011 в 22:59
  • 2
    @RichardHolloway: gnome-open делает не называть xdg-open, это наоборот! Таким образом, проблема заключается в gvfs-open (преемник или gnome-open) – MestreLion 23 May 2013 в 05:46
  • 3
    " больше не работает & quot ;? Этого никогда не было! xdg-open работает с помощью ассоциации mimetype, а файлы .desktop связаны с текстовыми редакторами, поскольку они являются подклассом текста – MestreLion 23 May 2013 в 05:47
  • 4
    это настолько глупо (что нет разумного способа запуска файла Desktop из терминала) – Sam Watkins 21 June 2014 в 09:23
  • 5
    Эта ошибка все еще существует? – Noitidart 3 March 2015 в 01:39

С любым недавним ubuntu, который поддерживает gtk-launch, просто перейдите в

gtk-launch <file> где имя файла .desktop без части .desktop

Итак gtk-launch foo открывает foo.desktop

Если <file> не находится в /usr/share/application или месте, где вы выполняете gtk-launch, команда gtk-launch <file> <uri>. (gtk-launch документация)

Используется с терминала или alt + F2 (alt + F2 сохраняет команду в истории так легкодоступной)

47
ответ дан 26 May 2018 в 01:13
  • 1
    Так и работает в debian. – nus 13 February 2015 в 21:51
  • 2
    gtk-launch firefox.desktop ~ / .local / share / applications / запускает firefox , просматривая каталог ~ / .local / share / applications / для меня. Кажется, что если вы были правы, firefox не должен был передавать каталог файла .desktop в качестве аргумента. На самом деле каталог, переданный в gtk-launch, не должен использоваться для поиска директории, содержащей файл .desktop (и на самом деле это не так) – Croad Langshan 28 February 2015 в 20:35
  • 3
    Ура! Ответ, который работает! – Alicia 13 February 2016 в 02:51

На сегодняшний день (12.10) ошибка все еще присутствует. Это действительно зависит от того, как работает gvfs-open (называемый xdg-open).

Тем не менее, мне удалось быстро обходное решение (крадущее вдохновение из исходного кода Nautilus). Это немного запутанно, но безупречно работает на Ubuntu 12.10, добавив значащую иконку (не более ?) в Unity launcher.

Сначала я написал скрипт python с помощью Gio и поместил его в качестве ~/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-open something.desktop работает так, как ожидалось, [hashbang] поверх исполняемого файла рабочего стола тоже

Это будет бесполезная работа, когда gvfs-open решит ошибку, но в тем временем ...

36
ответ дан 26 May 2018 в 01:13
  • 1
    Это работает лучше, чем ответ Хэмиша Даунера , поскольку он будет иметь дело с несколькими параметрами Exec= и % в команде правильно. – Flimm 11 January 2013 в 15:31
  • 2
    Спасибо за код - я на Lucid, и я просто сохранил это как /usr/bin/xdg-openpy и дал ему chmod +x - и использовал launcher.launch([],context) вместо ...None,context) (из-за " TypeError: argument 1: Должна быть последовательность, а не NoneType "). Теперь xdg-openpy app.desktop работает из командной строки (и все как обычно при двойном щелчке app.desktop), и он может напоминать мне, если я попытаюсь позвонить в терминал xdg-open и нажать вкладку. Ура! – sdaau 13 February 2013 в 01:40
  • 3
    +1. Это единственный ответ, который не требует ручного анализа файла .desktop, поэтому это самый разумный (и безопасный) подход. Также использует современные gi.repository вместо устаревших pygtk, так здорово! :) – MestreLion 23 May 2013 в 05:39
  • 4
    На самом деле, это вопрос, связанный с ответом Карло Пеллегрини. Я новичок, пожалуйста, исправьте меня, если есть лучший способ разместить его. Скрипт работает очень хорошо, но значок, который я нахожу в Unity, не является значком, определенным в файле .desktop, но значок по умолчанию команды Exec'ed. Есть идеи по этому поводу? – Ingo Leonhardt 24 May 2013 в 19:23
  • 5
    @Noitidart напишите последний ответ, который привел mo, чтобы сделать некоторые google, и я нашел , что . Не проверял, но, возможно, это помогает – Ingo Leonhardt 5 March 2015 в 16:36

Правильный путь

Вы действительно должны использовать 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, которая временно устанавливает желаемый [d5 ] .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 как скрипт «все-в-одном»; мы можем даже показать сообщение об ошибке и выйти с кодом возврата 1 в случае, если команда Exec не найдена:

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

Вышеупомянутые команды будут:

Найти строка, начинающаяся с Exec = Удалить Exec = Удалить любые переменные Exec (например, %f, %u, %U). Их можно заменить позиционными аргументами, как это предусмотрено спецификацией, но это может значительно усложнить проблему. См. Последнюю спецификацию рабочего стола. Выполнение команды Немедленно выйдите с соответствующим кодом выхода (чтобы не выполнять несколько строк Exec)

Обратите внимание, что этот AWK-скрипт обращается к нескольким краевым случаям, которые могут быть или не быть надлежащим образом устранены некоторыми другими ответы. В частности, эта команда удаляет несколько переменных Exec (если не удалять символ%), будет выполняться только одна команда линии Exec и будет вести себя как ожидалось, даже если команда линии Exec содержит один или больше знака равенства (например, script.py --profile=name).

Просто несколько других предостережений ... Согласно спецификации, Exec :

Путь к исполняемый файл на диске, используемый для определения того, действительно ли программа установлена. Если путь не является абсолютным путем, файл просматривается в переменной среды $ PATH. Если файл отсутствует или если он не является исполняемым, запись может быть проигнорирована (например, не используется в меню).

Имея это в виду, нет смысла исполнять его значение.

Некоторые другие проблемы - это Path и Exec . Путь состоит из рабочего каталога для запуска программы. Терминал - это логическое значение, указывающее, запускается ли программа в окне терминала. Все это можно решить, но нет смысла изобретать колесо, поскольку уже есть реализация спецификации. Если вы хотите реализовать Path, имейте в виду, что system() создает подпроцесс, поэтому вы не можете изменить рабочий каталог, выполнив что-то вроде system("cd \047" working_directory "\047"); system(command). Однако вы могли бы сделать что-то вроде system("cd \047" working_directory "\047 && " command). Примечание. \ 047 - одинарные кавычки (поэтому команда не разбивается на пути с пробелами).

Альтернатива Python

Я краду страницу у Карло, которая предложила создать скрипт Python для использования модуля Path . Вот минимальный способ выполнить один и тот же код из оболочки без необходимости создавать файл и беспокоиться о вводе / выводе.

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 не является обязательным. Кроме того, проверка ошибок не выполняется, поэтому вы хотите убедиться, что пусковая установка существует и доступна для чтения (перед ее использованием), если вы хотите, чтобы ваш скрипт был долговечным.

19
ответ дан 26 May 2018 в 01:13

Хотя OP не спрашивал о KDE, для тех, кто использует KDE, можно использовать следующую команду:

kioclient exec <path-to-desktop-file>

18
ответ дан 26 May 2018 в 01:13
  • 1
    Приобретено, потому что оно работает. Не нужно запускать KDE вообще, если у вас установлена ​​эта программа. – basic6 12 February 2015 в 23:24
  • 2
    Есть ли способ сделать это? Я скомпилировал clementine player, у которого есть ошибка, которая возникает только при запуске через .desktop-файл (с плазменной оболочкой). И я не могу понять, как иметь выходной журнал журнала anywere. – Kwaadpepper 16 November 2015 в 18:22
  • 3
    @Kwaadpepper вы можете использовать ваш файл .desktop для запуска сценария оболочки, который внутренне запускает вашу команду и перенаправляет вывод в файл. – Raman 18 November 2015 в 12:03
exo-open [[path-to-a-desktop-file]...]

, похоже, работает в версии 13.10, если exo-utils установлен (как в случае с Xubuntu).

10
ответ дан 26 May 2018 в 01:13
  • 1
    В самом деле? Теперь я открываю файл .desktop в Windows Notepad, а не системный редактор Linux, который бы открыл его с помощью xdg-open. Не улучшение. – Auspex 27 October 2014 в 06:44
  • 2
    Да, просто протестировали его в Ubuntu Studio 14.04. КСТАТИ. xdg-open и gvfs-open работают тоже. – jarno 28 October 2014 в 20:53
  • 3
    Работает также в 15 – Jonathan 2 May 2015 в 21:25
  • 4
    Использование Debian с xfce. Прекрасно работает! – king_julien 23 April 2017 в 17:58

Вы можете использовать dex.

dex foo.desktop
10
ответ дан 26 May 2018 в 01:13
  • 1
    ИМХО - это правильный ответ: один инструмент, один вызов только с параметром. Это то, что я искал, чтобы проверить написанные вручную файлы .desktop. И он может создавать файлы .desktop, тоже, yay! :-) – Axel Beckert 31 July 2016 в 18:42
  • 2
    Отлично! Если вы добавите файл .desktop, который использует dex gist.github.com/stuaxo/4169fc1342c496b7c8f7999188f2f242 в / usr / share / applications /, вы сможете запускать файлы рабочего стола в файловом менеджере без их открытия в gedit по умолчанию тоже. – Stuart Axon 19 December 2016 в 15:47

Добавление к ответу Хэмиша.

Учитывая сценарий deskopen, вы можете использовать ссылку на него как строку shebang в Addendum to answer. file, так как комментарий символ все еще #. То есть, поставьте это как первую строку файла .desktop:

#!/usr/bin/env deskopen

Затем поместите файл .desktop в качестве исполняемого файла (например, с помощью chmod +x whatever.desktop) , а затем вы можете

path/to/whatever.desktop

и voilà - приложение откроется! (В комплекте с файлом значка, который я указал, хотя я понятия не имею, как это сделать.)

Теперь, если вы также хотите, чтобы deskopen проходил через любые параметры командной строки, вы можете вместо этого использовать эту слегка модифицированную версию:

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

В стороне, я попытался использовать "#{@:2}" вместо shift ing, но он продолжал давать мне «плохую замену» ...

8
ответ дан 26 May 2018 в 01:13
  • 1
    Я знаю, что это более подходящий комментарий к ответу Хэмиша, но я новый пользователь и не допущен к комментариям. Ну что ж! – pabst 10 February 2012 в 02:14
  • 2
    Если у вас есть репутация, самое подходящее действие - это отредактировать этот ответ. – Flimm 13 September 2012 в 17:58
  • 3
    Ударьте, что любой может предложить изменения, даже пользователи, которые не вошли в систему! Это ни к чему. – Flimm 11 January 2013 в 15:33
  • 4
    Это ответ сам по себе, его штраф. – Bruno Pereira 11 January 2013 в 15:34
  • 5
    вы можете использовать "${@:1}" вместо shift, но для #! shebang требуется bash вместо sh. ИМХО Ваш первоначальный подход к смене проще и лучше – MestreLion 23 May 2013 в 06:00

В настоящее время приложение не делает то, что вы описываете в архивах Ubuntu. В настоящее время предпринимаются усилия по созданию общего решения для интеграции в настольные среды (например, openbox), которые не соответствуют этим спецификациям XDG.

Arch Linux работает над внедрением xdg-autostart на основе в библиотеках python-xdg. Из того, что я могу найти, это кажется еще не полным, но имеет некоторые сообщения об успехе.

Существует также реализация xdg-autostart на C ++ на gitorious (http://gitorious.org/xdg- autostart /), который, вероятно, выиграет от более широкого использования.

Если какое-либо из решений работает для вас, рассмотрите вопрос о предоставлении необходимой работы для включения в Debian или Ubuntu.

Чтобы использовать любой инструмент с openstart, вы бы назвали его в /etc/xdg/openbox/autostart.sh (если я правильно читаю документацию Openbox). Если это не сработает, вы можете вызвать его в любом из скриптов инициализации сеанса openbox.

6
ответ дан 26 May 2018 в 01:13
  • 1
    Не то, что я хотел бы услышать, в любом случае спасибо за информацию – enzotib 6 July 2011 в 21:09

У меня нет немедленного решения, удовлетворяющего требованию «использовать стандартную команду», но если вы хотите минимально разобрать файлы .desktop или хотите создать псевдоним Bash, тогда должно работать следующее: [ ! d0] awk -F= '/Exec=/{system($2); exit}' foo.desktop

другой подход, который может быть интересным, - это создать метод binfmt-misc на уровне ядра, чем совпадения в файлах .desktop (см. grep -r . /proc/sys/fs/binfmt_misc/ для этих паттернов что вы в настоящее время активировали).

В конце дня «с помощью стандартной команды» где-то придется разбирать файлы .desktop, это всего лишь вопрос как «стандарт / значение по умолчанию».

6
ответ дан 26 May 2018 в 01:13
  • 1
    Спасибо, интересно. В качестве "стандартного" Я имею в виду что-то, предоставленное DE и соответствующее freedesktop.org. – enzotib 10 July 2011 в 13:48
  • 2
    Направьте для awk, а не цепочку из grep s и sed s. – jmtd 21 October 2013 в 15:57
  • 3
    Upvote, хотя он не работает (или лучше - работает слишком много), если у вас есть Exec= линии: / – Devenv 4 December 2017 в 13:46

При попытке протестировать эти файлы я нашел самый простой способ проверить, что DM или менеджер сеансов будут делать то, что я ожидал, чтобы открыть окружающий каталог в браузере папок пользовательского интерфейса, а затем дважды щелкните, чтобы открыть их.

Если вы находитесь в командной строке: gvfs-open . или gnome-open . откроют его в браузере настроенных папок.

. Команда sed не будет отражать поведение DM, в том числе такие вещи, как fiddy stuff убегает и цитирует, где вам действительно не хотелось бы альтернативного поведения. Это не командная строка, но она проверяет все. Я также нашел установку Terminal=true полезной для отладки.

1
ответ дан 26 May 2018 в 01:13
  • 1
    Терминал немедленно исчезает, у меня нет времени, чтобы увидеть сообщение при использовании Terminal = true: s – gouessej 29 October 2015 в 15:53

Этот SO ответ на этот вопрос дал мне понять: не пытайтесь выполнить файл рабочего стола, выполните файл, указанный в файле рабочего стола.

Например, execute / home / jsmith / Рабочий стол / x11vnc.sh

Exec=/home/jsmith/Desktop/x11vnc.sh
1
ответ дан 26 May 2018 в 01:13

Я взял сценарий из ответа Карло выше и попытался улучшить его для моего собственного использования на рабочем столе.

Эта версия скрипта позволит вам запускать любое приложение, как если бы вы ввели его на HUD, если это, скорее всего, первый результат. Он также позволяет передавать аргументы файла для файлов .desktop, которые не поддерживают 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
ответ дан 26 May 2018 в 01:13

Убедитесь, что сценарий, на который указывает ваш рабочий стол, также является исполняемым.

Если все еще не работает. Сделайте рабочий стол рабочего стола в терминале, изменив Terminal=true и поместив его в сценарий bash. Запустите скрипт, чтобы поймать вывод ошибки. Замените ошибку, если исправлены ошибки.

0
ответ дан 26 May 2018 в 01:13

Ответ Хэмиша велик, но я хотел бы предложить более простую альтернативу, с меньшим количеством задействованных труб:

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

В этом случае awk ищет строку начиная с Exec, а затем мы просто печатаем поля после этой строки, используя для цикла и = печатаем поле 2, т. е. все, что приходит после этого поля. Кудрявые скобки на концах команд $(...) - это замена параметров, поэтому shell будет выполнять любую команду awk; в этом случае возвращается фактическая команда, которая появляется после Exec=.

В некоторых редких случаях может быть более одного знака =, что по-прежнему возможно. Для этого я предлагаю

$(awk -F= '/^Exec/||/^TryExec/ {for(i=2;i<=NF;i++) print $i;exit}' /usr/share/applications/firefox.desktop)
0
ответ дан 26 May 2018 в 01:13
  • 1
    Ницца, awk и Serg =) – A.B. 21 August 2015 в 22:56
  • 2
    И иногда, есть TryExec, возможно, вы должны проверить свою вторую команду =) – A.B. 21 August 2015 в 22:57
  • 3
    @ A.B. Хе-хе, awk - мое оружие выбора, когда дело доходит до обработки текста. Кроме того, синтаксис близок к C. О, и уже добавил TryExec часть ^ _ ^ – Sergiy Kolodyazhnyy 21 August 2015 в 22:59
  • 4
    У меня есть +1 =) – A.B. 21 August 2015 в 23:00
  • 5
    Но что это %f, %u, %U или что-то вроде этого за командой? – A.B. 21 August 2015 в 23:01

Другие вопросы по тегам:

Похожие вопросы: