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

Из того, что я могу собрать, .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 файл с терминала?

gtk-запуск

С любой последней версией Ubuntu, поддерживающей gtk-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-запуск запускает приложение, используя указанное имя. Приложение запускается с соответствующим уведомлением о запуске на дисплее по умолчанию, если не указано иное.

gtk-запуск принимает по крайней мере один аргумент - имя запускаемого приложения. Имя должно совпадать с именем файла рабочего стола приложения, находящегося в /usr/share/application, с суффиксом ".desktop" или без него.

Можно использовать с терминала или Alt + F2 (Alt + F2 сохраняет команду в истории, чтобы она была легко доступна).

Ответ должен быть таким

xdg-open program_name.desktop

Но из-за ошибка (здесь на восходящем потоке) это больше не работает.

Современный Ответ

gtk-launch <app-name> - где <app-name> является именем файла .desktop файл, с или без .desktop расширение.

Видеть еще один ответ в этой теме для получения более подробной информации. Я получил эту информацию из этого ответа.

Устаревшие инструменты оболочки ответ

Написано давным-давно - см. Комментарии под этим ответом о том, почему этот подход не будет работать для многих файлов рабочего стола.

Выполняемая команда содержится внутри файла рабочего стола, которому предшествует 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 и т.д.) подробно описаны здесь. Ни один из них не имеет отношения к запуску из командной строки.

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

Тем не менее, мне удалось быстро найти обходной путь (позаимствовав вдохновение из исходного кода nautilus). Он немного запутан, но работает безупречно в Ubuntu 12.10, добавляя значимый значок (не более ?) на панели запуска Unity.

Во-первых, я написал скрипт на python с использованием Gio и поместил его как ~/bin/run-desktop :

#!/usr/bin/pythonfrom gi.repository import Gioimport 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.0Name=run-desktopExec=run-desktop %UMimeType=application/x-desktopTerminal=falseType=Application

Наконец, я связал запись с обработчиком по умолчанию в ~/.local/share/applications/mimeapps.list под [Default Applications] раздел как :

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

Сейчас:

  • xdg-open что-то.рабочий стол работает так, как ожидалось
  • #!/usr/bin/xdg-openhashbang поверх исполняемой записи на рабочем столе тоже работает

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

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

Вы действительно должны использовать gtk-launch если он доступен. Обычно это часть пакета libgtk-3-bin (это может варьироваться в зависимости от дистрибутива).

gtk-launch используется следующим образом:

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

Пожалуйста, обратите внимание, что gtk-launch требует, чтобы .рабочий стол файл, который будет установлен (т.е. находится в /usr/share/applications или ~/.local/share/applications).

Итак, чтобы обойти это, мы можем использовать небольшую хакерскую функцию Bash, которая временно устанавливает желаемый .рабочий стол файл перед его запуском. "Правильный" способ установки .рабочий стол файл находится через 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

Ручная альтернатива

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

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

Если вы хотите лечить awk команда похожа на сценарий "все в одном"; мы даже можем показать сообщение об ошибке и завершить работу с кодом возврата 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. Найдите строку, начинающуюся с Исполнительный директор=
  2. Удалять Исполнительный директор=
  3. Удалите все переменные Exec (например %f, %u, %U). Можно заменить их позиционными аргументами, как это предусмотрено спецификацией, но это значительно усложнило бы проблему. Смотрите последние новости Спецификация ввода рабочего стола.
  4. Выполните команду
  5. Немедленно завершите работу с соответствующим кодом выхода (чтобы не выполнять несколько Выполнение линии)

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

Просто еще несколько предостережений... В соответствии со спецификацией, Попробуйте выполнить является:

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

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

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

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

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

launch(){# Usage: launch PATH [URI...]python - "$@" <<EOFimport sysfrom gi.repository import GioGio.DesktopAppInfo.new_from_filename(sys.argv[1]).launch_uris(sys.argv[2:])EOF}

Затем выполните функцию запуска следующим образом:

launch ./path/to/shortcut.desktop

Обратите внимание, что использование URI является необязательным. Кроме того, проверка ошибок не выполняется, поэтому вам нужно убедиться, что программа запуска существует и доступна для чтения (перед ее использованием), если вы хотите, чтобы ваш скрипт был долговечным.

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

kioclient exec <path-to-desktop-file>

В Fedora это включено в kde-runtime оборотов в минуту.

Вы могли бы использовать Декс.

Установите dex:

sudo apt install dex

Запустите файл с его помощью:

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

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

(Составлено из различных других ответов здесь)

В зависимости от вашей системы и различных ошибок, которые могут существовать или не существовать в вашей системе, попробуйте выполнить следующие действия, пока один из них не сработает:

  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-запуске: такого приложения нет";
  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') & # Работает

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

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

#!/usr/bin/env deskopen

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

path/to/whatever.desktop

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

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

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

В качестве отступления я попытался использовать "#{@:2}" вместо shifting, но это продолжало давать мне "плохую замену"...

ПРИМЕЧАНИЕ: Причина сбоя вашего exec заключается в том, что exec заменяет ваш текущий запущенный процесс указанным вами процессом, поэтому вы попытались заменить свою оболочку запуском рабочего стола в виде скомпилированного двоичного файла. Причина, по которой вы не смогли “sudo exec”, заключается в том, что это встроенная оболочка, а не двоичная команда.

По теме: Hashbang для файлов Gnome .desktop

Интересно, мне было интересно, почему это привело к закрытию вкладки.

Я вижу, они в конечном итоге анализируют файл .desktop. В любом случае спасибо вам за ссылку.