Из того, что я могу собрать, .desktop
файлы являются ярлыками, которые позволяют настраивать параметры приложения. Например, у меня их много в папке /usr/share/applications/
.
Если я открою эту папку в nautilus
, я могу запустить эти приложения, просто дважды щелкнув соответствующий файл, например, Двойной щелчок firefox.desktop
запускает Firefox. Тем не менее, я не могу найти способ сделать то же самое через терминал.
Если я сделаю gnome-open foo.desktop
, он просто откроет foo.desktop
в виде текстового файла. Если я сделаю его исполняемым, а затем запустим его в bash, он просто потерпит неудачу (что, как ожидается, явно не является сценарием bash). РЕДАКТИРОВАТЬ: Doing exec /fullpath/foo.desktop
дает мне сообщение Permission denied
, даже если я меняю владельца на себя. Если я выполняю исполняемый файл и выполняю ту же команду, вкладка терминала, которую я использую, просто закрывается (я предполагаю, что она вылетает). Наконец, если я сделаю sudo exec /fullpath/foo.desktop
, я получу сообщение об ошибке sudo: exec: command not found
.
Это мой вопрос, как мне запустить файл foo.desktop
из терминала?
gtk-launch
- где
- это имя файла . файл 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
Вы можете поместить ее в файл, скажем ~/in/deskopen
с содержимым
#!/bin/sh
$(grep '^Exec' $1 | tail -1 | sed 's/^Exec=//' | sed 's/%.//' | sed 's/^"//g' | sed 's/" *$//g') &
Затем сделать ее исполняемой
chmod +x ~/bin/deskopen
И затем вы можете сделать это, e. g.
deskopen /usr/share/applications/ubuntu-about.desktop
Аргументы (%u
, %F
и т.д.) подробно описаны здесь. Ни один из них не имеет отношения к запуску из командной строки.
Ответ Хэмиша отличный, но я хотел бы предложить более простую альтернативу с меньшим количеством каналов:
$ (awk -F = '/ ^ Exec / || / ^ TryExec / {print $ 2; exit} '/usr/share/applications/firefox.desktop)
В этом случае awk
ищет строку, начинающуюся с Exec
, а затем мы просто печатаем поля после этой строки, используя цикл for и =
, мы печатаем поле 2, то есть все, что идет после этого поля. Фигурные скобки на концах команд $ (...)
- это подстановка параметров, поэтому оболочка выполнит все, что возвращает команда awk; в этом случае он возвращает фактическую команду, которая идет после Exec =
.
В некоторых редких случаях может быть более одного знака =
, что все еще возможно. Для этого я предлагаю
$(awk -F= '/^Exec/||/^TryExec/ {for(i=2;i<=NF;i++) print $i;exit}' /usr/share/applications/firefox.desktop)
Убедитесь, что скрипт, на который указывает ваш файл рабочего стола, также является исполняемым.
Если по-прежнему не работает. Сделайте файл рабочего стола доступным для запуска в терминале, изменив Terminal = true
и поместив его в сценарий bash. Запустите сценарий, чтобы перехватить вывод ошибки. Вернуть назад, когда ошибки будут исправлены.
(Скомпилировано из различных других ответов здесь)
В зависимости от вашей системы и различных ошибок, которые могут существовать или не существовать в вашей системе, попробуйте следующие, пока один из них не сработает:
xdg-open имя_программы.desktop
exo-open имя_программы.desktop
gtk-launch имя_программы.desktop
kioclient exec имя_программы.desktop
dex имя_программы.desktop
Обратите внимание, что в системах Ubuntu средства запуска рабочего стола «меню Пуск» доступны в / usr / share / applications /
.
В качестве примера, чтобы показать, какие из вышеперечисленных команд работают, а какие нет. т работать над моя система Ubuntu 14.04, вот результаты для меня следующих вызовов:
xdg-open /usr/share/applications/eclipse_for_cpp.desktop
# Ошибка из-за ошибки (пытается заставить меня сохранить этот файл .desktop) exo-open /usr/share/applications/eclipse_for_cpp.desktop
# Работает gtk-launch /usr/share/applications/eclipse_for_cpp.desktop
# Сбой с "gtk-launch: no such application " kioclient exec /usr/share/applications/eclipse_for_cpp.desktop
# Работает dex /usr/share/applications/eclipse_for_cpp.desktop
#pt install, & sudo ado
не удается найти пакет dex Я взял скрипт из -ответа Карло - выше, и попытался улучшить его для использования на моем собственном рабочем столе.
Эта версия скрипта позволит вам запускать любое приложение так, как если бы вы ввели его на 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)
Exec=/home/jsmith/Desktop/x11vnc.sh
Вы можете использовать dex .
dex foo.desktop
Tôi không có giải pháp tức thì nào đáp ứng yêu cầu cho "sử dụng lệnh chuẩn" , nhưng nếu bạn muốn phân tích cú pháp tối thiểu .desktop
tệp hoặc muốn tạo bí danh Bash, thì điều sau sẽ hoạt động:
awk -F = '/ Exec = / {system ($ 2); exit} 'foo.desktop
một cách tiếp cận khác có thể thú vị là tạo phương thức binfmt-misc cấp nhân
so với các phương thức phù hợp trên tệp .desktop
(xem grep -r. / proc / sys / fs / binfmt_misc /
cho những mẫu mà bạn hiện đã bật).
Vào cuối ngày, một cái gì đó sẽ phải phân tích cú pháp tệp .desktop
, đó chỉ là một câu hỏi về "tiêu chuẩn / mặc định".
Пытаясь протестировать эти файлы, я нашел самый простой способ проверить, что DM или диспетчер сеансов будут делать то, что я ожидал, - открыть окружающий каталог в браузере папок пользовательского интерфейса, а затем дважды - щелкните, чтобы открыть их.
Если вы находитесь в командной строке: gvfs-open.
или gnome-open.
откроет его в настроенном обозревателе папок.
sed не будет отражать поведение DM, включая такие неприятные вещи, как побеги и цитирование там, где вам действительно не нужно альтернативное поведение. Это не командная строка, но она все проверяла. Я также обнаружил, что параметр Terminal = true
полезен для отладки.
В настоящее время нет приложения, которое выполняет то, что вы описываете в архивах Ubuntu.В настоящее время идет работа над созданием общего решения, обеспечивающего интеграцию сред рабочего стола (например, openbox), которые не соответствуют этим спецификациям XDG.
Arch Linux работает над реализацией xdg-autostart на основе python- xdg библиотеки. Судя по тому, что я могу найти, это кажется еще не полностью завершенным, но есть некоторые отчеты об успехе.
Существует также реализация на C ++ xdg-autostart на gitorious (http://gitorious.org/xdg-autostart/), которая вероятно, выиграет от более широкого использования.
Если какое-либо решение работает для вас, рассмотрите возможность отправки необходимой работы для включения в Debian или Ubuntu.
Чтобы использовать любой инструмент с openstart, вы должны вызвать его в / etc / xdg /openbox/autostart.sh (если я правильно читаю документацию openbox). Если это не сработает, вы, вероятно, можете вызвать его в любом из сценариев инициализации сеанса openbox.
exo-open [[path-to-a-desktop-file]...]
похоже работает в релизе 13.10, если установлен exo-utils (как в случае с Xubuntu).
Пока OP не спрашивал о KDE, для любого, кто работает с KDE, может быть использована следующая команда:
kioclient exec
On Fedora, это включено в kde-runtime
rpm.
Ответ должен быть
xdg-open program_name.desktop
С любой последней версией Ubuntu, поддерживающей gtk-launch
] просто перейдите в
gtk-launch <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 сохраняет команду в истории, поэтому она легко доступна).
Ошибка все еще присутствует с 2006 года. Фактически это зависит от того, как gvfs-open
(вызывается xdg-open
) работает.
Тем не менее, мне удалось быстро найти обходной путь (позаимствованный из исходного кода наутилуса). Он немного запутан, но работает безупречно в Ubuntu 12.10, добавляя значимый значок (не более ?
) на панели запуска Unity.
Сначала я написал сценарий 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]
....
application/x-desktop=run-desktop.desktop
Теперь:
xdg-open
something.desktop работает должным образом #! / usr / bin / xdg-open
hashbang поверх исполняемой записи рабочего стола тоже работает Это будет бесполезно, когда gvfs-open
исправит ошибку, но пока ...
Добавление к ответу Хэмиша.
Учитывая сценарий deskopen, вы можете использовать ссылку на него в качестве строки shebang в файле .desktop , поскольку символ комментария по-прежнему #
. Иными словами, поместите это как первую строку файла .desktop :
#!/usr/bin/env deskopen
Затем отметьте файл .desktop как исполняемый (например, с помощью chmod + x Any.desktop
), а затем вы можете
path/to/whatever.desktop
и вуаля - Приложение откроется! (В комплекте с указанным мной файлом значка, хотя я понятия не имею, как это сделать.)
Теперь, если вы также хотите, чтобы deskopen передавал любые параметры командной строки, вы можете вместо этого использовать эту слегка измененную версию:
#!/bin/sh
desktop_file=$1
shift
`grep '^Exec' "${desktop_file}" | sed 's/^Exec=//' | sed 's/%.//'` "$@" &
Как Кроме того, я пытался использовать "# {@: 2}"
вместо shift
ing, но это продолжало давать мне «плохую замену» ...
Вам действительно стоит использовать 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
как универсальный сценарий; мы даже можем показать сообщение об ошибке и выйти с кодом возврата 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}}'
Вышеупомянутые команды будут:
% f
, % u
, % U
). Их можно заменить позиционными аргументами, как предусмотрено в спецификации, но это значительно усложнит проблему. См. Последнюю версию Desktop Entry Specification . Обратите внимание, что это Сценарий AWK обращается к нескольким крайним случаям, которые могут или не могут быть должным образом решены некоторыми другими ответами. В частности, эта команда удаляет несколько переменных Exec (стараясь в противном случае не удалить символ%), выполнит только одну строчную команду Exec и будет вести себя так, как ожидалось, даже если Строка команды Exec содержит один или несколько знаков равенства (например, script.py --profile = name
).
Еще несколько предостережений ... Согласно спецификации, TryExec :
Путь к исполняемому файлу на диске, используемый для определения, действительно ли установлена программа. Если путь не является абсолютным, файл ищется в переменной среды $ PATH. Если файл отсутствует или не является исполняемым, запись может быть проигнорирована (например, не может использоваться в меню).
Имея это в виду, не имеет смысла выполнять его значение.
Некоторые другие проблемы: Путь и Терминал . Путь состоит из рабочего каталога для запуска программы. Терминал - это логическое значение, которое указывает, запускается ли программа в окне терминала. Все это можно решить, но нет смысла изобретать велосипед, поскольку уже есть реализации спецификации. Если вы действительно хотите реализовать Путь , имейте в виду, что system ()
порождает подпроцесс, поэтому вы не можете изменить рабочий каталог, выполнив что-то вроде system ("cd \ 047 "рабочий_каталог" \ 047 "); система (команда)
. Однако вы, вероятно, могли бы сделать что-то вроде system (команда "cd \ 047" working_directory "\ 047 &&")
. Примечание \ 047 - это одинарные кавычки (чтобы команда не прерывалась на путях с пробелами).
Я краду страницу у Карло здесь , который предложил создать Python скрипт для использования модуля gi . Вот минимальный способ выполнить тот же код из оболочки, не создавая файла и не беспокоясь о вводе-выводе.
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 не является обязательным. Кроме того, проверка ошибок не выполняется, поэтому вы должны убедиться, что программа запуска существует и доступна для чтения (перед ее использованием), если вы хотите, чтобы ваш сценарий был надежным.